Re: Formátovaný tisk bylo Re: sprintf - co delam blbe?

Tomáš Hamouz konfery.tomas.hamouz na seznam.cz
Středa Duben 17 09:39:17 CEST 2024


Moje oblíbená metoda je předat ten cílový buffer v parametru, nejlépe
i s délkou, a funkce vrátí pointer na ten buffer. Te to okopčené ze
standardní libc, ale mám dojem že to zatím nezaznělo.


char* my_format_fn(char* buffer, size_t buflen, params...)
{
}


   ...
   char buf[XX];
   printf("bla bla %s bla bla", my_format_fn(buf, sizeof(buf), dalsi
   parametry...));



Výhody
 - není problém s vlákny
 - není problém s alokací a dealokací
 - lze používat přímo ve výrazu
Nevýhody
 - víc parametrů

Tom83



>> Jen mi není jasné, zda a kdy se pole buf na haldě uvolní.

> Musel by to explicitne uvolnovat volajuci, potom, co sa cely string pouzije
> (vytlaci, skopiruje - znova, neviem, co robi arduinovsky serial volaco).

> Dynamicka alokacia pamate je peklo s viacerymi diablami, ktoreho pouzitie v
> mcu musi byt mimoriadne dobre odovodnene a ako prva volba sa musi velmi
> dobre zvazit aj napisanie vlastneho alokatora. 

> Tento pripad podla mna ani zdaleka nepatri medzi odovodnene.

>> V rámci testování bing chatu 

> Moznost, ktoru zrejme nepouziva nikto, alebo nikto sa k nej verejne
> nepriznava, a tym padom bing o nej ani nemoze vediet, je mat globalne pole
> vyhradene priamo pre tuto ulohu (t.j. vytvaranie formatovacich retazcov).
> Tiez je tam "problem s vlakny" (t.j. nereentrantnost toho riesenia),
> dokonca to ani nemusia byt vlakna ale aj "ocakavana zivotnost" toho
> retazca (t.j. problem, ze vysledny retazec musi byt cely
> pouzity/vytlaceny/skopirovany, skor nez je dana funkcia znova zavolana).

> Dalsia moznost je vytvaranie formatovacich retazcov in situ, t.j. priamo v
> mieste pouzitia. Napr. ak vypisy idu cez seriak, tak priamo do nejakeho
> buffra ktory tam pre ten seriak uz aj tak pravdepodobne existuje.

> Obe tieto moznosti sa v skutocnosti prelinaju s relativne castym (co
> dokazuje "google hlasovanie" v modernej verzii "bing doporucuje") riesenim
> "volajuci musi zabezpecit miesto"; rozdiel je vo filozofii. Predstavme si,
> ze formatovaciu funkciu pise osoba A a zvysok programu osoba B. V pripade
> "volajuci musi zabezpecit miesto" osoba A napise funkciu bez ohladu na
> zvysok programu a predpise osobe B vsetky poziadavky, ktore B musi splnit
> aby sa dana funkcia mohla pouzit. V pripade, ze funkciu pise B a to potom,
> co uz boli urobene dolezite rozhodnutia o tom, ako program ma vyzerat, ta
> funkcia sa prisposobi filozofii celeho programu, napr. ak ma vediet pisat
> in-situ do kruhoveho buffera, no tak je napisana s ohladom na tuto
> poziadavku.

> Ako vravim, v mcu neexistuje "najlepsie" riesenie, vsetko je kontextovo
> zavisle. Pre Arduino/C++ je ta implicitna instanciacia cez navratovu
> hodnotu (ak to skutocne funguje dobre a nie su s tym spojene nejake
> chytaky) celkom dobre riesenie, lebo v Arduine sa aj tak nehra na
> efektivnost.

> wek




> ----- Original Message ---------------

> Takže takto? Je to opravdu kratší.

> char * Fultoa(uint32_t val,uint8_t length,uint8_t decimal) {
>    uint8_t ld1 = length - decimal - 1;
>    uint8_t ld2 = ld1 - 1;
>    char * buf = (char *)malloc(11);
>    uint32_t k=100;
>    for (uint8_t i = 3;i < length; i++) k*=10;
>    ultoa(val+k, buf, 10);
>    for (uint8_t i = 0; i < ld2; i++) {
>      if (buf[i + 1] == '0')
>        buf[i] = ' ';
>      else
>        buf[i] = buf[i + 1];
>    }
>    buf[ld2] = buf[ld1];
>    buf[ld1] = '.';
>    return buf;
> }

> Jen mi není jasné, zda a kdy se pole buf na haldě uvolní.

> Martin Záruba

> Dne 17.4.2024 v 8:08 Ladislav Vaiz napsal(a):
>> On 17.04.2024 7:44, Martin Záruba wrote:
>>> String Fultoa(uint32_t val, uint8_t length, uint8_t decimal) {
>>>   uint8_t ld1 = length - decimal - 1;
>>>   uint8_t ld2 = ld1 - 1;
>>>   char buf[11];
>>>   uint32_t k=100;
>>>   for (uint8_t i = 3;i < length; i++) k*=10;
>>>   ultoa(val+k, buf, 10);
>>>   for (uint8_t i = 0; i < ld2; i++) {
>>>     if (buf[i + 1] == '0')
>>>       buf[i] = ' ';
>>>     else
>>>       buf[i] = buf[i + 1];
>>>   }
>>>   buf[ld2] = buf[ld1];
>>>   buf[ld1] = '.';
>>>   return buf;
>>> }
>>
>>
>> V rámci testování bing chatu jsem mu zkusil zadat optimalizaci pro 
>> AVR. Navrhl místo Stringu vracet static char buf[11] definovaný ve 
>> funkci. U toho zmínil problém s vlákny (což na AVR nebude tak horké), 
>> k tomu navrhl řešení pomocí pole definovaného volajícím a předávaného 
>> funkci.
>>
>> To poslední mi připadne nejlepší. Vyhnete se režiji Stringu a buffer 
>> bude alokován, jen když ho volající bude potřebovat.
>>
>> L.

> _______________________________________________
> HW-list mailing list  -  sponsored by www.HW.cz
> Hw-list na list.hw.cz
> http://list.hw.cz/mailman/listinfo/hw-list



Další informace o konferenci Hw-list