Assegnazione su struct

ciao a tutti.
So che a molti sembrera' banale, ma davvero non riesco a capire.

tento di fare questo:

typedef struct
{
  char IDDevice [12];
  int SoilMost;
  int SoilMostx100;
  char Hod [3];
  char Mod [3];
  char Dom [3];
  char Moy [3];
  char Year [5];
}  record_type ; 

RTC_DATA_ATTR int XLoop = 0;
RTC_DATA_ATTR char* XDevice;
RTC_DATA_ATTR record_type XRecord[6];

void setup() {
}
void loop() {
  Serial.print(XDevice);
  XLoop=0;
XRecord[XLoop].IDDevice  = "HegoProbe01";
}

e mi dice questo:
sketch_sep16a:24:28: error: invalid conversion from 'const char*' to 'char' [-fpermissive]
XRecord[1].IDDevice [12] = "HegoProbe01";
^~~~~~~~~~~~~
exit status 1
invalid conversion from 'const char*' to 'char' [-fpermissive]

Non capisco perche'. Ho anche previsto lo spazio in piu' per il carattere di fine stringa.
Scusate il quesito banale, ma evidentemente mi sta sfuggendo qualcosa di macroscopico.
grazie

P.S. ovviamente lo skectch riportato e' solo un 'estratto' che faccio girare cosi per cercare di rimuovere tutte le altre possibili cause.

Non c'entra la "struct", è prioprio un errore di sintassi ... NON si può assegnare così una stringa ad un char array ... quello lo puoi fare SOLO quando la definisci, es:

char mioNome[] = "Guglielmo";

... in tutti gli altri casi devi usare le apposite funzioni che trovi in string.h ed in particolare, in questo caso, la strcpy().

Guglielmo

Il tuo è un errore classico ma non grave...

Anzi lascio il campo libero: sta rispondendo uno bravo

grazie Gugliemo. ci guardo subito.
Negli anni 80 programmavo in clipper....... le cose erano piu' facili :slight_smile:

... anche io :grin:

Guglielmo

Ah allora non sono il solo... :wink:

1 Like

mi sa che l'80% veniamo tutti da li e dal commodore :slight_smile:

... Apple II+ :grin:

... mi sa che all'80% ... siamo tutti sopra i 60 anni (io 65) :smile:

Guglielmo

io 61

1 Like

Guglielmo, sai perché?... Anch'io ci sono cascato e mi è sembrato illogico, incomprensibile.

Ah ecco, questo mi rincuora :slight_smile:

Oltretutto, solo ora sto cominciando a raccapezzarmi con le varie librerie. Non ero abituato a cambiare istruzioni tenendo conto alla libreria caricata. Ho riempito quindi lo sketch con 1000 'dialetti' presi da esempi su internet , ma ognuno da librerie differenti......

Oppure ancora meglio:

constexpr char *mioNome = "Guglielmo";

Ma questo è C++. In C sarebbe:

const char * const mioNome = "Guglielmo";

mioNome non può puntare altrove perché costante, come pure il contenuto "Guglielmo" non posso modificarlo a run-time.

PS: Pure io Clipper (Un C molto semplificato tendente al C++)

Ciao.

Clipper anche io, ma ero a scuola

1 Like

Si, ok, ma NON era questo lo scopo ...

... lo scopo era far vedere che, in fase di dichiarazione di un array di char puoi assegnare il valore con '=', dopo, in corso d'opera, non puoi assegnargli un altro valore sempre con '=' ma devi farlo con strcpy() e quindi ... perché confondere le idee e creare un valore costante a cui non devo/posso riassegnare un valore?

Ribadico che:

  1. il modo corretto di definire una stringa classica di caratteri è:

char nomeStringa[N]; dove N è la dimensione in caratteri -1 (il terminatore 0x00).

  1. In fase di definizione è possibile assegnare un valore iniziale con la forma

char nomeStringa[N] = "xxxxxxxxxxxx"; dove gli xxxx devono essere massimo N-1 caratteri

  1. Nel corso del programma si può cambiare il contenuto della suddetta stringa, sempre rimanendo nel limite di N-1 caratteri, usando la funzione strcpy().


Tutto il resto uno se lo va a studiare DOPO che ha capito i concetti di base :slight_smile:

Guglielmo

Sono questi i concetti base. :grinning:

Chi confonde le idee? non è mica detto che la literal "HegoProbe01" debba essere incorporata, può anche dichiarare una o più costanti.

La struttura sarebbe ora così:

typedef struct
{
  char *IDDevice;

Ora funziona questa:

XRecord[XLoop].IDDevice = mioNome;

e pure questa funziona:

XRecord[XLoop].IDDevice = "HegoProbe01"

Ti assicuro che non voglio confondere le idee, ma questo è C e le costanti string si dichiarano come ho scritto.

Lo scritto mille volte, il compilatore è più bravo di noi a contare perché allora consigli questa:

char nomeStringa[N] = "xxxxxxxxxxxx"; dove gli xxxx devono essere massimo N-1 

Ciao.

... ancora con queste costanti ??? ma chi ti ha parlato di costanti? ma se deve riassegnargli il valore cosa cavolo c'entrano le costanti? :angry:

Perché tu ancora NON hai capito che a lui serve una variabile char di dimensione che decide lui poiché poi, dinamicamente, nel corso del programma, gli riassegna dei valori con la strcpy() ... se gli serve da 50 o 100 caratteri che fa scrive 50 o 100 caratteri tra apici per assegnare il valore massimo iniziale così lo calcola il compilatore? :face_with_raised_eyebrow:

Ma per favore ...

Guglielmo

Certo che non l'ho capito, non ha scritto che vuole incorporarla, tra l'altro così si ritrova con due C string in memoria ram, una la literal che esiste sempre più la copia. Visto che la literal è sempre presente perché non usare un puntatore come ho mostrato io?

PS:Io mica leggo nel pensiero degli utenti. :grinning:
Ciao.

Va beh, lasciamo stare, parliamo due lingue differenti :roll_eyes: ...
... fortuna che l'OP ha capito quello che deve fare, lo ha fatto ed ha anche messo risolto alla discussione.

Chiudiamo qui.

Guglielmo

Scusa ma perché te ne esci così?

Ha dichirato XRecord globale, allora ha due possibilità, una di queste è usare strcpy, sempre se è necessario. L'altra è quella che ho mostrato.

Mi viene solo un buon motivo per incorporare la literarl string; solo quando vuoi serializzare una struttura dati per spedirla byte per byte.

Ora cosa ci deve fare non lo ha detto e quindi se gli serve incorporarla usa strcpy, se non serve incorporarla usa il puntatore.

Tra l'altro nessuno gli ha fatto notare che:

Serial.print(XDevice);

non stamperà nulla poiché XDevice è dichiarato come puntatore globale che per default viene inizializzato al valore di default che è zero o nullptr. Per fortuna la print fa un controllo sul puntatore.

Se fosse stato locale sarebbe sua responsabilità inizializzarlo almeno a nullptr.

PS: Si mi rendo conto che parliamo un altra lingua. Reciprocamente il mio dire non entra nel tuo capire. :smiley:

Ciao.

Non volevo scatenare diatribe fra scuole di pensiero. Oltretutto vi seguo a fatica :slight_smile:
Ad ogni modo per adesso, ho risolto e fa quello che volevo facesse.
Devo preparare un array di 6 record in memoria non volatile , che poi sara' letto e spedito in una volta sola ad un database on cloud (Influxdb). Sbagliavo a fare le assegnazioni per mia ignoranza sulle stringhe.

Adesso me la sono cavata cosi
RTC_DATA_ATTR char XDevice[] = "HegoProbe01";

e poi

strcpy(XRecord[XLoop].IDDevice, XDevice);
  XRecord[XLoop].SoilMostx100 = soilmoisturepercent;
  strftime(XRecord[XLoop].Hod, 3, "%H", &timeinfo);
  strftime(XRecord[XLoop].Mod, 3, "%M", &timeinfo);
  strftime(XRecord[XLoop].Dom, 3, "%d", &timeinfo);
  strftime(XRecord[XLoop].Moy, 3, "%m", &timeinfo);
  strftime(XRecord[XLoop].Year, 5, "%Y", &timeinfo);
  XLoop++;

scrivo poi i record sul DB.
Adesso si apre il problema di organizzare appropriatamente i dati su influxdb, perche' assieme al valore da visualizzare sul grafico, vorrei accoppiasse la stringa col MIO timestamp che ho preparato per ogni punto, ma questo e' un'altro topic....

Grazie a tutti per i vostri commenti e insegnamenti (che dovro' rileggermi almeno 10 volte)...