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

Wiring, C++, C, Java, ...
Pravidla fóra
Toto subfórum slouží k řešení obecných otázek kolem programování (konstrukce, knihovny, alokace paměti, ...)
Odpovědět
martinius96
Příspěvky: 579
Registrován: 01 srp 2017, 19:29
Reputation: 0
Bydliště: Poprad
Kontaktovat uživatele:

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

Příspěvek od martinius96 » 19 led 2020, 01:19

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
    	} 
}

ondraN
Příspěvky: 932
Registrován: 08 srp 2019, 20:01
Reputation: 0

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

Příspěvek od ondraN » 19 led 2020, 08:31

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.

Uživatelský avatar
gilhad
Příspěvky: 778
Registrován: 07 bře 2018, 11:22
Reputation: 0

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

Příspěvek od gilhad » 19 led 2020, 09:27

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.

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 13 hostů