Octave - error: strread: the number of output variables must match that specified by FORMAT

10 risposte [Ultimo contenuto]
Ritratto di guido.bonalumi
Offline
Geek
Iscritto: 04/07/2012
Messaggi: 70

Ciao a tutti,
cercando di utilizzare del codice per Matlab, fornitomi da un professore, con Octave (versione 3.6.2) mi viene restituito l'errore in oggetto che riporto qua sotto:
error: strread: the number of output variables must match that specified by FORMAT
Qualcuno saprebbe dirmi che significa di preciso e come risolvere?
Vi ringrazio anticipatamente per l'aiuto che saprete darmi.

Ritratto di mandian
mandian
(Geek)
Offline
Geek
Iscritto: 16/05/2011
Messaggi: 129

Citazione:

error: strread: the number of output variables must match that specified by FORMAT

significa che hai lanciato una qualche funzione in Octave che fornisce in output un certo numero di variabili, ma nel chiamarla ne hai indicato un numero diverso.

Difficile dirti di più se non posti almeno la frazione di codice che produce l'errore (in genere Octave indica la riga corrispondente all'errore).

ciao,
M

Ritratto di guido.bonalumi
Offline
Geek
Iscritto: 04/07/2012
Messaggi: 70

Non ho postato il codice semplicemente perchè si tratta di codice matlab che su matlab funziona, quindi pensavo potesse trattarsi di un problema noto legato alla funzione strread. Comunque vi fornisco subito maggiori dettagli... l'errore completo è il seguente:

error: strread: the number of output variables must match that specified by FORMAT
error: called from:
error:   /usr/share/octave/3.6.2/m/io/strread.m at line 179, column 5
error:   /usr/share/octave/3.6.2/m/io/textscan.m at line 221, column 11
error:   /media/6C209D8E209D5FBE/Users/Guido/Documents/Università/CFD/Advection-Diffusion/octave/rdinp.m at line 13, column 3
error:   /media/6C209D8E209D5FBE/Users/Guido/Documents/Università/CFD/Advection-Diffusion/octave/main.m at line 6, column 14

Per quanto riguarda il codice matlab invece gli errori fanno riferimento a queste linee:
- La riga 13 del file rdinp.m è la seguente:
c = textscan(fid,'%*s',1,'headerlines',1);
- Mentre la riga 6 del file main.m è la seguente:
[bt,bd,fld] = rdinp (file);
Qualunque ipotesi è ben accetta! Smile
Già che ci sono vi chiedo anche un'altra cosa... prima di questo errore mi compariva un warning (che se non erro non è un problema che compromette l'esecuzione del codice, come avviene invece per gli error), il quale faceva riferimento al simbolo "|"; l'ho sostituito con "&&", ma è corretto? Sapreste dirmi la differenza? Ora il warning non compare più, ma non vorrei che si trattasse di un errore quella sostituzione. Se rimettessi il simbolo "|" il codice funzionerebbe comunque?

Ritratto di mcortese
mcortese
(Moderatore)
Offline
Moderatore
Iscritto: 27/02/2009
Messaggi: 2918

Leggendo il sorgente di strread si direbbe che non ammette che il numero di dati da leggere (e ritenere) sia zero:

  if (max (nargout, 1) != nfields)
    error ("strread: the number of output variables must match that specified byFORMAT");
  endif

Infatti l'espressione "max (qualcosa, 1)" valse sempre almeno 1, mentre nfields nel tuo caso vale zero perché l'espressione '%*s' significa leggi-e-dimentica una stringa, quindi i campi da leggere-e-ritenere sono zero.

Mi sembra che sia un baco di Octave, perché, oltre a essere incoerente con Matlab, non è documentato da nessuna parte che il numero di campi da leggere letti dev'essere almeno 1.

D'altro canto, che cosa può mai servire un'istruzione che non restituisce assolutamente niente? Serve solo per "mangiare" una riga di input? Se è così, sarebbe meglio togliere l'asterisco, leggere-e-ritenere l'intera stringa e memorizzarla in una variabile inutile, tipo:

dummy = textscan(fid,'%s',1,'headerlines',1);
e poi semplicemente non usare mai dummy.

Ritratto di mcortese
mcortese
(Moderatore)
Offline
Moderatore
Iscritto: 27/02/2009
Messaggi: 2918

guido.bonalumi ha scritto:

Già che ci sono vi chiedo anche un'altra cosa... prima di questo errore mi compariva un warning (che se non erro non è un problema che compromette l'esecuzione del codice, come avviene invece per gli error), il quale faceva riferimento al simbolo "|"; l'ho sostituito con "&&", ma è corretto? Sapreste dirmi la differenza? Ora il warning non compare più, ma non vorrei che si trattasse di un errore quella sostituzione. Se rimettessi il simbolo "|" il codice funzionerebbe comunque?


Non mi sembra che | e && siano la stessa cosa! Il primo è un "or" il secondo un "and". Se proprio devi sostituire "a | b" con qualcosa, puoi usare "or(a,b)". Ma forse faresti meglio a specificare qual era il warning che ti dava.

Ritratto di guido.bonalumi
Offline
Geek
Iscritto: 04/07/2012
Messaggi: 70

Ti ringrazio per la risposta, ma non ci ho capito nulla! Big Grin
A parte gli scherzi qualcosa ho intuito, ma non ho ben chiara la soluzione... dovrei modificare il codice di strread (ammesso di sapere come e non penso proprio di saperlo) oppure, come mi pare di aver capito dal tuo suggerimento, quello di matlab (cosa che comporterebbe il capire precisamente cosa fa quel codice prima di intervenire)?

Ritratto di guido.bonalumi
Offline
Geek
Iscritto: 04/07/2012
Messaggi: 70

Per quanto riguarda il warning ammetto di non essermi documentato prima e mi rendo conto della domanda idiota... Big Grin! In ogni caso il warning preciso era il seguente:
warning: /media/6C209D8E209D5FBE/Users/Guido/Documents/Università/CFD/Advection-Diffusion/rdinp.m: possible Matlab-style short-circuit operator at line 41, column 28
L'operatore a cui fa riferimento è ovviamente " | ".

Ritratto di mcortese
mcortese
(Moderatore)
Offline
Moderatore
Iscritto: 27/02/2009
Messaggi: 2918

Il mio suggerimento era quello di sostituire, nel programma Matlab che ti ha fornito il tuo prof, la riga incriminata (quella con "%*s") con quella che ti ho indicato (quella con "%s"). La differenza sta nell'asterisco, che significa pressapoco: leggi una stringa, ma dimenticala subito, non memorizzarla da nessuna parte. Per un baco (forse) Octave non supporta bene quando "%*s" è l'unica cosa da leggere. Per cui la mia versione è invece: leggi una stringa, e memorizzala in una variabile, anche se tanto io poi non la userò mai.

Quanto al warning, non mi preoccuperei a meno di non trovare risultati strani. In un'espressione tipo "a || b", se a vale VERO, non c'è bisogno di valutare b, perché tanto "VERO or b" vale VERO per qualsiasi valore di b. Se l'interprete sfrutta questa proprietà e omette di valutare b in tali casi, allora si dice che applica il cortocircuito. Non tutti i linguaggi lo prevedono. Ad esempio in C, che lo prevede, è lecito scrivere

zero_or_small_percentage = (amount == 0) || (total / amount > 10);

Se amount vale zero, la valutazione non prosegue oltre il segno || e quindi non si avrà mai una divisione per zero; se invece non vale zero, allora la seconda parte dell'or viene valutata, ma a qual punto la divisione è sempre lecita.

Il Visual Basic, invece, non lo prevede, quindi questo frammento fallisce quando amount vale zero:

zero_or_small_percentage = (amount = 0) Or (total / amount > 10)

In Octave, gli operatori || e && hanno il cortocircuito, mentre gli operatori |, & e le funzioni and() e or() non ce l'hanno. Matlab è quasi uguale, con una eccezione: all'interno di un'istruzione if o while, gli operatori | e & godono di cortocircuito, negli altri casi no.

Può darsi che il warning segnali proprio uno di questi casi in cui Matlab e Octave differiscono.

Ritratto di guido.bonalumi
Offline
Geek
Iscritto: 04/07/2012
Messaggi: 70

Ti ringrazio molto per la spiegazione completa ed esaustiva! Ora ho davvero capito e farò come mi hai suggerito! Ti chiedo solo un'altra cosa per pura curiosità... se il comando "%*s", come dici, legge una stringa e poi la dimentica subito (almeno in matlab) qual'è il senso di un tale comando!?

Ritratto di mcortese
mcortese
(Moderatore)
Offline
Moderatore
Iscritto: 27/02/2009
Messaggi: 2918

Supponi di dover leggere una riga composta da 3 parole e di essere interessato solo alla prima e alla terza:

[prima, terza] = strread(stringa, "%s %*s %s");

Nota che la dimensione del vettore a sinistra dell'uguale è pari a 2: 3 parole lette, meno 1 da scartare = 2. Il problema è quando le parole lette sono tutte da scartare. In quel caso Octave protesta (e secondo me è un baco) mentre Matlab, a quanto pare, no.

Ritratto di guido.bonalumi
Offline
Geek
Iscritto: 04/07/2012
Messaggi: 70

Tutto chiarissimo!!! Grazie mille! Appena ho un minuto provo a vedere se con i tuoi consigli il codice gira e poi metterò "Risolto". Grazie ancora.