Selezione file con uigetfile

di il
5 risposte

Selezione file con uigetfile

Ciao! Devo caricare una serie di file .txt con diverse colonne di numeri ed elaborarli. Seleziono i file tramite uigetfile e si crea una struttura di tipo cell di dimensioni 1xn (n=numero di file selezionati).
Adesso dovrei prelevare ogni singolo elemento, convertirlo in stringa e caricare il file nel workspace con load. In pratica devo creare un vettore di stringhe di dimensione n in cui ogni elemento corrispondente al nome del file da caricare.
Ho provato questo codice ma ovviamente non funziona !!!
file=uigetfile('*.txt','Multiselect','on');
n=length(file);
for i=1:n
    dati(i)=char(file(i));
end
Mi da il seguente errore:
??? Subscripted assignment dimension mismatch.
dati(i) dovrebbe contenere i nomi dei file in formato stringa per poi caricarli con load, cioè fare una sorta di:
for i=1:n
    a(i)=load(dati(i));
end
Qualcuno mi può aiutare??? Spero di essere stato chiaro!!!

5 Risposte

  • Re: Selezione file con uigetfile

    Il motivo per il quale lo script inserito nella domanda
    
    file=uigetfile('*.txt','Multiselect','on');
    n=length(file);
    for i=1:n
        dati(i)=char(file(i));
    end
    
    genera un messaggio di errore sono i seguenti:

    [*] la variabile "file" è un cellarray che contiene tanti elementi quanti sono i files selezionati con "uigetfile"
    [*] il loop scandisce tutti gli elementi del cellarray "file", per cui, ad ogni iterazione "file(i)" conterrà il nome (e solo il nome) di uno dei file. Nel caso servisse anche avere il "path", l'istruzione

    "file=uigetfile('*.txt','Multiselect','on');"

    deve essere modificata in questo modo:

    "[file,path]=uigetfile('*.txt','Multiselect','on');"

    [*] la variabile "data", per come viene usata nel loop è un vettore di caratteri
    [*] con l'istruzione

    "dati(i)=char(file(i))"

    si cerca di assegnare il contenuto dell'i-esimo elemento del cellarray "file" (che è una stringa di caratteri) ad un singolo carattere, "dati(i)"
    Questo genera il messaggio di errore perchè la dimensione della stringa "file(i)" è > 1

    Per correggere lo script basta sostituire l'istruzione

    dati(i)=char(file(i));

    con l'istruzione:

    load(char(file(i)))

    Ad ogni iterazione del loop l'istruzione carica (load) il contenuto dell'i-esimo file di testo nel workspace.
    Questa modifica rende inutile il successivo loop riportato nella domanda.
    I dati contenuti nel file di testo vengono assegnati ad una variabile (vettore o matrice) che avrà lo stesso nome del file di testo.

    Se si vuole modificare il nome della variabile appena letta, si può usare la funzione "eval" per creare una nuova variabile (il nome della quale deve essere "costruito" all'interno del loop) ed assegnargli il contenuto letto dal file.

    La soluzione proposta è stata implementata nello script in calce.
    
    file=uigetfile('*.txt','Multiselect','on');
    %
    % Codice aggiunto per gestire la selezione del tasto "Annulla"
    %
    if(isequal(file,0))
       disp('Selezione files annullata dall''utente')
    else
       n=length(file);
       for i=1:n
          %
          %    Codice originale
          %
          %%%%%%%%%    dati(i)=char(file(i));
          %
          %     Codice modificato: lettura dei files di testo e creazione nel
          %     workspace di una variabile con il nome uguale a quello del file
          %     di input
          %
          load(char(file(i)));
       end
    end
    
    Hope this helps.
  • Re: Selezione file con uigetfile

    Ok grazie, così carico il file nel workspace con il suo nome, ma il problema è che io poi devo utilizzare questi file per l'elaborazione ma non conosco inizialmente i propri nomi. Come faccio ad assegnare ogni nome del file ad una variabile?
  • Re: Selezione file con uigetfile

    Non sono sicuro di aver capito la domanda:
    non conosci in anticipo il nome dei files da caricare?

    andrew89 ha scritto:


    Ok grazie, così carico il file nel workspace con il suo nome, ma il problema è che io poi devo utilizzare questi file per l'elaborazione ma non conosco inizialmente i propri nomi. Come faccio ad assegnare ogni nome del file ad una variabile?
    Se è così come puoi pensare di utilizzarne in contenuto per qualsiasi elaborazione?

    Se si vuole importare un file di testo in modo "semplie" (es. con la funzione "load") il file deve contenere solo numeri (e tutte le righe devono avere lo stesso numero di colonne).

    Se il file contiene delle righe di testo di intestazione che, eventualmente, ne spieghino il contenuto, l'importazione del file di testo diventa un po' più complicata (puoi trovare nelle recenti domande inserite nel Forum, diverse soluzioni).

    Per il resto non posso che ripetere quanto scritto nella risposta precedente:

    ask_raf ha scritto:


    I dati contenuti nel file di testo vengono assegnati ad una variabile (vettore o matrice) che avrà lo stesso nome del file di testo.

    Se si vuole modificare il nome della variabile appena letta, si può usare la funzione "eval" per creare una nuova variabile (il nome della quale deve essere "costruito" all'interno del loop) ed assegnargli il contenuto letto dal file.
    Non c'è bisogno di assegnare esplicitamente dei nomi alle variabili lette da un file di testo.

    I dati importati dal file di testo vengono assegnati ad un'unica variabile.
    Se il file di testo "file_1.txt", per esempio, contiene 10 righe x 3 colonne di numeri, la funzione "load" carica nel workspace i 30 numeri creando una matrice (10x3) di nome "file_1", come nell'esempio che segue:

    Contenuto del file "file_1.txt"
    1838	2216	2308
    2970	1758	1745
    1584	741	2785
    1439	2000	1741
    2405	251	51
    684	1878	363
    1495	1983	2589
    2703	2190	1453
    1724	2673	2535
    2536	2947	629
    
    
    %
    % Lettura del file di testo "file_1.txt"
    %
    load('file_1.txt')
    %
    % lista delle variabili presenti nel workspace
    %
    whos file_1
    
      Name         Size            Bytes  Class     Attributes
      file_1      10x3               240  double              
    
    file_1 =
            1838        2216        2308
            2970        1758        1745
            1584         741        2785
            1439        2000        1741
            2405         251          51
             684        1878         363
            1495        1983        2589
            2703        2190        1453
            1724        2673        2535
            2536        2947         629
    
    Hope this helps.
  • Re: Selezione file con uigetfile

    Ok forse non mi sono spiegato bene!!! Io ho ad esempio 5 file .txt (A B C D E) ognuno dei quali ha 3 colonne di soli numeri tutte con le stesse righe. Io conosco i nomi dei file però poi ogni volta devo selezionare file diversi (a volte A B C, a volte B C, altre volte B C D, ecc.). Per questo ho bisogno di una variabile in cui vado a salvare i nomi dei file in modo da utilizzarli nell'elaborazione successiva, in modo indipendente dai file che vado a selezionare.
    Spero di essere stato più chiaro!!!
  • Re: Selezione file con uigetfile

    A prescindere dal fatto di riuscire a risolvere il problema del nome delle variabili e dei files, sinceramente mi riesce sempre più difficile capire cosa effettivamente debba fare il programma che si vuole scrivere.

    Nell'ultima domanda si legge che anche il numero dei files da importare può variare.

    Cosa contengono i files?
    Sono dati che dovranno essere "uniti" per creare, ad esempio, un'unica matrice?
    I nomi dei files contengono qualche indicazione sul loro contenuto?

    In caso di selezione multipla, la funzione uigetfile ritorna la lista dei files selezionati ordinati alfabeticamente a prescindere, quindi, dall'ordine con il quale sono stati selezionati.

    Se il resto del programma è già stato scritto, questo userà delle variabili che dovrebbero contenere i dati letti, ma come vengono gestiti il fatto che i dati letti (le matrici) nel caso specifico, possono essere tre oppure due (nel caso, ad esempio che si leggano - come riportato nella domanda - "a volte A B C, a volte B C")?

    Per poter risolvere definitivamente il problema dell'importazione serve che venga pubblicata la descrizione del programma o il programma stesso in modo da capire come assegnare i nomi alle variabili ed associarli ai nomi dei files.

    Per il momento quello che si può fare, ma non credo sarà di molta utilità, è modificare il codice che è stato proposto nella precedente risposta, come segue:

    all'interno del loop di lettura viene creato un vettore di strutture ("data_struct") con due campi:
    - mat: contenente la matrice letta dal file di testo
    - f_name: stringa che contiene il nome del file di testo dal quale è stata letta la matrice "mat"

    La struttura può essere usata (ad esempio in un ciclo for) per ricercare uno specifico nome di file; se trovato, si avrà a disposizione la relativa matrice.

    Come detto sopra, però, senza ulteriori informazioni su:
    - cosa contengono i files di testo (nel senso di che tipo di dati e che relazione c'è tra i diversi files)
    - in che modo il programma deve operare sui dati, una volta letti: quindi descrizione del programma o listato dello stesso
    dubito di poter fare altro.
    
    file=uigetfile('*.txt','Multiselect','on');
    %
    % Codice aggiunto per gestire la selezione del tasto "Annulla"
    %
    if(isequal(file,0))
       disp('Selezione files annullata dall''utente')
    else
       n=length(file);
       for i=1:n
          %
          %    Codice originale
          %
          %%%%%%%%%    dati(i)=char(file(i));
          %
          %     Codice modificato: lettura dei files di testo e creazione nel
          %     workspace di una variabile di tipo "struct" con due campi:
          %        - mat:    contiene la matrice letta dal file di testo
          %        - f_name: stringa che contiene il nome del file di testo dal
          %                  quale è stata letta la matrice "mat"
          %
          data_struct(i).mat=load(char(file(i)));
          data_struct(i).f_name=char(file(i));
       end
    end
    
    Hope this helps.
Devi accedere o registrarti per scrivere nel forum
5 risposte