Comparazione di stringa letta da un array

Ciao a tutti

Ho problemi nella comparazione di una stringa letta da un array che utilizza PROGMEM. Non mi funziona questa parte:

const char varPippo1[] PROGMEM="Qualcosa";
...
const char varPippo5[] PROGMEM="";

while(pippo)
{
strcpy_P(pippo, (PGM_P)pgm_read_word(&(Puntatore[z])));
lcd.setCursor(0,1); lcd.print(pippo);
delay(100);
z+=1;
...
}

Sul display leggo tutte le stringhe, ma quando arriva a "" non si ferma. Che cosa legge oltre a ciò che scrivo? Un carattere "Return" o qualcosa di simile?

Ho provato anche a scrivere "END" al posto di "" e poi l'ho confrontato con una stringa contenente "END", ma non funziona ugualmente...

Grazie
Gianluca

Il puntatore è valido anche se punta a una stringa vuota, quindi sarà sempre true. Quindi o metti NULL al posto di "", oppure nella condizione metti strlen(pippo) > 0. Ma allora sarebbe meglio fare diventare il ciclo un do... While.

PS: Stai usando un Array di Array, vero?

Eh... Ci sto litigando per la seconda volta, dopo che la prima non avevo concluso nulla! Nonostante 30 anni di elettronica, avevo scritto solo qualcosa in Basic con il C64 e con il C mi mancano basi importanti e fatico anche molto a capire certe cose.

pippo è una stringa in cui viene scritto "Qualcosa" o altro. Non è il puntatore, no?...

P.s.: prima del while sarebbe necessario scrivere pippo="unacosaacaso". Il fatto che funzioni ugualmente conferma il problema.

SukkoPera:
PS: Stai usando un Array di Array, vero?

Sì. E' un array di char[].

con const char pippo5[] PROGMEM=NULL; ci sono errori.

Adesso con strlen(pippo)>0 funziona. Inizialmente, come detto, ho dovuto mettere
char pippo[]="Qualcosa";

Grazie! :slight_smile:

La dichiarazione dell'array dovrebbe essere così:

const char s1[] PROGMEM = "Pippo";
const char s2[] PROGMEM = "Paperino";
const char s3[] PROGMEM= "Paperoga";

const char* ss[] PROGMEM = {s1, s2, s3, NULL};

E quindi ci puoi lavorare con qualcosa del genere:

PGM_P s;
int i;
for (i = 0; (s = reinterpret_cast<PGM_P> (pgm_read_ptr (&ss[i]))); i++) {
    Serial.println (s);
}

Se preferisci lavorare solo coi puntatori:

const char **sptr;
PGM_P s;
for (sptr = ss; (s = reinterpret_cast<PGM_P> (pgm_read_ptr (sptr))); ++sptr) {
    Serial.println (s);
}

Non garantisco (soprattutto sulla seconda che, anzi, sono quasi certo che non funzioni, se riesco correggo stasera con un Arduino sotto mano), sono andato a memoria :).

Nota comunque l'uso di pgm_read_ptr(). In giro tutti usano pgm_read_word(), che su AVR funziona, perché i puntatori tengono 16 bit, ma è concettualmente sbagliato e non portabile.

Per cortesia, mi spieghi perché se funziona strlen(pippo)>0 non funziona anche pippo!="" ?

Se strlen(pippo) è zero (nessun carattere), non dovrebbe anche essere pippo uguale a "" (nessun carattere)?

Grazie

pippo!="" non funziona per lo stesso motivo per cui non funziona pippo!="END" ed invece devi usare strcmp(pippo,"END")
Devi confrontare il "contenuto" di pippo e della stringa (C like) che per di più sono array.
pippo!="" stai confrontando il puntatore pippo con l'indirizzo ad una stringa vuota.

Cioè: se A e B sono stringhe, io non posso fare if(A==B)?...
Perdonatemi per una domanda simile ma forse non mi è mai capitato di provare a farlo...

Edit: Ah! pippo è un puntatore!

Scusa, ma se pippo è un puntatore che senso ha scrivere strlen(pippo)? Uhmm...

Forse è un buffer? Facendo String pluto=String(pippo) potrei poi fare cose del tipo if(pluto=="END") ?

Esatto, in C le stringhe non si possono comparare direttamente, perché sono vettori di caratteri. Inoltre, il nome di un vettore è di fatto un puntatore al suo inizio. Quindi, in sostanza, le stringhe si manipolano tramite puntatori.

Per confrontarle si usa strcmp(), come già suggerito, che prende come argomenti i puntatori alle due stringhe e confronta i loro contenuti.

Con un semplice if (a!=b) confronti i puntatori, per cui l'if sarà sempre vero, a meno che a e b non puntino esattamente alla stessa stringa.

Nota, infine, che se invece usi la classe String (cosa sconsigliatissima in un ambiente ristretto come Arduino), invece il confronto diretto è perfettamente lecito, in quanto la classe definisce gli operatori di confronto.

PS: Se una delle stringhe sta in flash, devi usare strcmp_P() e metterla al secondo posto.