Deklarace pole stringů
Ahoj, mám dotaz...
je možné deklarovat pole proměnných typu String, pokud dopředu nevím kolik toho bude? Např:
String test[] = {"","","","",""};
mi udělá pole stringů test[0] až test[4].
String test[]="";
nebo
String test[];
udělá co?
Co to udělá můžeš vyzkoušet, ne? Práce se stringy se také liší podle programovacího jazyka...
A ten tajnej programovací jazyk je...?
programuju Arduino, ESP8266, ESP32, attiny... takže nejspíš c++, prostě to co používá Arduino IDE, pardon za neuvedení...
Kdyz si zvetsis to dolni okno (byvalo cerne s cervenymi napisy), tak bys mel byt schopen uvidet, co vsechno se tam spousti za programy a tedy i za prekladace a s jakymi parametry - pak uz si k nim najdes dokumentaci, co umi a co ne.
(Je to to okno, co tam pri nahravani lezou ukazatele, kolik se toho nahralo)
Jinak spis doporucuju https://forum.hwkitchen.cz/ kde jsou lidi, co to pouzivaji a neresi Terrabytove disky, ale par Kilobytovou pamet. A predtim procist priklady a serialy (tutorialy a clanky) na https://bastlirna.hwkitchen.cz/
Muzes deklarovat pole stringu, aniz bys znal velikost pole, ale pak budes muset to pole alokovat podle potreby a do te promenne podstrcit a sampmzrejme si hlidat, abys neprekrocil aktualni meze.
Nebude ti spravne fungovat, kdyz ho deklarujes bez rozsahu a pak do nej budes pridavat. (Jako asi se chvili bude zdat, ze to funguje, ale pak nakjednou zjistis, ze se ti divne meni nejruznejsi promenne a nic nefunguje jak ma, protoze se ti nehlidaji meze a prepisujes pamet, co ti nepatri)
Obecne bych se spis klonil k tomu udelat to ciste prez nejakou dynamickou strukturu typu seznam, nebo B-tree, nebo cokoli jineho potrebujes / lepe se hodi pro tvuj ucel.
A u Arduina (a podobnych mrnavosti, co maji malo RAM) bych byl s dynamickymi alokacemi na halde docela opatrny, protoze pameti je malo a s trochou smuly ji muzes snadno fragmentovat (a nasledne vypotrebovat), nez se nadejes - dostanes se do stavu, ze alokovaneho nemas moc, ale presto nejde nic alokovat, protoze neni kde, i kdyz by ti teoreticky melo zbyvat jeste dost volne pameti. Ale prakticky nezbyva, protoze neni v dost velkem souvislem kuse.
A hratky se String (jakozto objektem, co si sam alokuje dynamicky pamet) se ve vetsim muzou ukazat zdrojem problemu. Ja davam prednost char * kde to jen jde a organizuju si to sam. Stejne jako vystupy delam radeji radou vypisu jednotlivych promennych, nez jejich sestavenim do Stringu a naslednym jedinym vypisem.
---
A ano Arduino je neco jako C++/G++ s knihovnou Wiring a radou knihoven casto dost pochybne kvality. Ale muzes tam pouzivat vetsinu konstrukci toho jazyka (IMHO skoro vsechny) a radu standardnich knihovnich funkci (ty urcite ne vsechny, protoze spousta toho tam neni kvuli velikosti).
Jo, to se mi stalo, když jsem deklaroval jeden ze stringů jako array o předem neznámé velikosti, pak se mi do něj začalo cpát něco, co jsem nepředpokládal (což jsem poznal tak, že jsem si to vypsal přes serial). Takže mi nezbylo, než deklarovat na přesný počet prvků a začalo to chodit.
Hraju si s TTGO T-display a mám na to napsanou jednoduchou meteostanici, která si tahá data přes wifi z openweathermap.org. Chtěl jsem tam přidat možnost, aby si to v cyklu načetlo více měst, ale zas jsem nechtěl, abych musel s každou změnou kódu okopávat hafo proměnnejch... no holt budu muset, jinak to nejde.
A co ti brání si říct, že třeba 25 měst max. by mohlo stačit, naalokovat si pole na 25 měst a vypisovat a pracovat dál jen s těmi vyplněnými?
Pak potřebuješ pole stringů a jednu proměnnou, kde budeš držet aktuální počet.
Jo, to by šlo. Tak to udělám.
Mimochodem seznam měst se hodí nahrát do EEPROM, já to tak mám v GPS (několik měst a jejich souřadnice), který provozuju už léta. Zůstalo teda u provizorních 4 měst (počítal jsem 0-30 na což mám dimenzované pole (je to pole struktur, struktura se skládá z názvu města a jeho souřadnic a možná tam je ještě něco), možná jsem tam i nějaká další města nahrál, program ale prostě používá jen 4 první položky a asi to tak zůstane navěky), ono plány vždy jsou velkorysé, realizace bývá omezená časem. Tato vznikla doslova pár hodin před dovolenou před léty a od té doby jsem se v tom nechtěl šťourat (a mezitím jsem vymyslel dvě nové verze hw, takže s tou starou se už asi těžko budu zabývat). Takže dodnes se mi ukazuje vzdálenost domu, do místa dovolené a do Wien Hbf a Roma Terminni (to byly přestupní uzly). Kromě vzdálenosti domu, jsou to teda zbytečné informace, zase tak často nepotřebuju vědět jak daleko jsem od Vídně nebo od Říma.
Když to takl vezmu, potřeboval bych někoho, kdo mé nápady na sw zrealizuje, já většinou zůstanu jen u základu (hw a opravdu nejnutnější sw nejnižší úrovně) a o moc víc se mi dělat nechce.
Jen taková malá úvaha: co si vytvořit jedno pole znaků, třeba o velikosti 1 kB a do něj sázet svoje stringy tak, že mezi nima použiješ rozumnej oddělovač, třeba jeden ze znaků: | = ~ atd. Předpokládám, že délky jednotlivých řetězců se už měnit nebudou.
Pak už jen pár funkcí: pro uložení novýho řetězce za poslední, získání řetězce z pole atd.
Klasicky je znak \0 pak jdou pouzivat i standardni funkce
Stringy v arduinu a v céčku jsou pro nezasvěcené taková alchymie. Už jen proto, že podobné proměnné (tj. pole a struktury) jsou z principu automaticky brané jako ukazatele, ale dochází nebo nedochází u nich k automatické dereferenci z čehož vyplývá právě ten zmatek (kdyby byla povinnost provádět dereferenci všude je to v pohodě, kdyby naopak se všude dereference dělala sama a adresu by si člověk musel vyžádat bylo by to také v pohodě, ale jak to je někde tak a někde jinak, je to vždy zmatek). Vím, že kdo se živí céčkem mi bude tvrdit, že je to jasné a jednoduché (i ve škole jsme se učili jak je to jednoduché, Herout to taky popisuje docela jednoduše) já osobně si teda musim v případě potřeby jednotlivé kousky kódu vyzkoušet na něcem jednodušším, nedokážu takové věci zařadit přímo do programu ani po několikerém nastudování příslušných kapitol Herouta.
Do toho se ještě přidává potřeba konstantních textových řetězců uložených v programové paměti nebo eeprom (definuje se direktivou PROGMEM, EEMEM), není totiž důvod textovými řetězci, jejichž hodnota se nemění (typicky zprávy uživateli) si zabírat ramku, které je v arduinu opravdu velmi málo, zatímco té programové je víc než dost. Ovšem nestačí to definovat jen jako const a ani nestačí potom takovou proměnnou použít, musí se přes pgm_read nebo ee_read kterým se předávbá ukazatel, ale ten se zase musí přetypovat a výsledek snad taky. To co píšu vlastně platí pro AVRStudio, v adruino ide moc nedělám (cokoliv složitějšího než nějaký základní ukázkový příklad se tam dělá dost blbě), arduino na to má definovaná nějaká makra, ale jiná pro třídu printable a jiná jinde, naštěstí se to dá okoukat z některých příkladů, kde to používají.