Stránka 1 z 1

String a char* - problémy pri strok a pretypovaní

Napsal: 19 led 2020, 01:19
od martinius96
Ahoj, programujem na ESP8266 (NodeMCU) XML parser.
ESP8266 je v úlohe webservera a prijíma dáta po HTTP protokole POST metódou od ďalších ESP8266 klientov. Dáta sú vo formáte XML (SOAP), je to vlastná implementácia pre OPC-UA webserver. Robil som si rôzne výpisy pre debug, kedy som si porovnával, či je na konkrétnom riadku payloadu nejaká hodnota (aby som vedel, že sa riadky načítavajú správne).
Načítaný Payload na webserveri vyzerá následovne:
Obrázek
Celý je uložený do premennej String x. Využívam funkciu strok, kedy si postupne z payloadu vyťahujem jednotlivé riadky s terminátorom \n, ktorým končí každý riadok. Premenná token tak obsahuje jednotlivé riadky ako pole znakov. Teda pre ľahšie porovnanie si pretypujem hodnotu char* token na String.

Vytvoril som si premennú String slovo = String(token); toto prejde v poriadku. Problém nastáva pri slučke while, kedy do premennej slovo priradím znova hodnotu token-u s pretypovaním String(token). Toto nefunguje. Podarilo sa to vyriešiť iba lokálne definovanou premennou v tomto cykle (String abc).

Zmena medzi oboma programami je teda iba v cykle while. V prípade, že je tam samostatná premenná String abc, funguje to OK, v prípade, že tam ponechám slovo a tomu priradím hodnotu, spadne to. (Spadne to ihneď po pripojení na WiFi). Vedel by mi niekto povedať, prečo sa takýto problém deje? Je to problém funkcie strok, alebo pretypovania token-u? Ďakujem. Zmena je vyznačená v oboch programoch.
Prípad 1: PADÁ

Kód: Vybrat vše

const char terminator[3] = "\n"; //terminátor. Každý riadok Payloadu je ukončený \n 
String x= server.arg("plain"); //Payload (ako na obrázku)
unsigned int y= x.length(); //dĺžka Payloadu
char str[y]; //pole
x.toCharArray(str, x.length()); //stringTocharArray
char* token; //char, ktorý obsahuje jednotlivé riadky
token = strtok(str, terminator); //Nacitam prvy riadok po  \n
String slovo = String(token); //token si pretypujem na String a priradím hodnotu do Stringu slovo
if (slovo.startsWith("<?xml version=")) {
    Serial.println("XML Payload"); 
}
while ( token != NULL ) {
	token = strtok(NULL, terminator); //nacitavam dalsie riadky
    	slovo = String(token); //String slovo ---------------------ZMENA
    	if (slovo.startsWith("<BME280_VALUE_PRESSURE>")) {
      		Serial.println("BME280 --> TLAK");
    	} 
}
Prípad 2: FUNGUJE OK

Kód: Vybrat vše

const char terminator[3] = "\n"; //terminátor. Každý riadok Payloadu je ukončený \n 
String x= server.arg("plain"); //Payload (ako na obrázku)
unsigned int y= x.length(); //dĺžka Payloadu
char str[y]; //pole
x.toCharArray(str, x.length()); //stringTocharArray
char* token; //char, ktorý obsahuje jednotlivé riadky
token = strtok(str, terminator); //Nacitam prvy riadok po  \n
String slovo = String(token); //token si pretypujem na String a priradím hodnotu do Stringu slovo
if (slovo.startsWith("<?xml version=")) {
    Serial.println("XML Payload"); //FUNGUJE OK
}
while ( token != NULL ) {
	token = strtok(NULL, terminator); //nacitavam dalsie riadky
    	String abc = String(token); //String abc ---------------------ZMENA
    	if (abc.startsWith("<BME280_VALUE_PRESSURE>")) {
      		Serial.println("BME280 --> TLAK"); //FUNGUJE OK
    	} 
}

Re: String a char* - problémy pri strok a pretypovaní

Napsal: 19 led 2020, 08:31
od ondraN
Já se tedy přetypování vyšších typů vyhýbám jak čert kříži. Důvodem je to, že nikdy nevím, jak přetypování vlastně dopadne a chyba se hledá velmi těžko. Může to naoko fungovat, ale při určitých datech se to po.... V tomhle připadě bych v cyklu nakopíroval prvky objektu string do pole, nebo pole do do stringu, podle momentální potřeby.

Re: String a char* - problémy pri strok a pretypovaní

Napsal: 19 led 2020, 09:27
od gilhad
No, hlavne String abc = String(token) NENI pretypovani, ale vytvoreni noveho objektu typu String a jeho prirazeni do promenne abc (jejiz platnost je omezena na telo toho while a pak je uvolnena).


slovo = String(token); opet NENI pretypovani, ale vytvoreni noveho objektu typu String a jeho prirazeni do promenne slovo (jejiz platnost je omezena na telo (pravdepodobne) loop() a uvolnena je az na konci sve platnosti). Co se deje s predchozimi objekty String do ni prirazenymi si ted z hlavy nejsem jist, ale je mozne, ze strasi nekde v pameti a ta dojde driv, nez je neco uklidi.