Fórum Root.cz

Hlavní témata => Vývoj => Téma založeno: Withy14 25. 11. 2015, 15:15:08

Název: Zápis do souboru - fflush vs fprintf
Přispěvatel: Withy14 25. 11. 2015, 15:15:08
Ahoj,
mám problém s fflush/fputs. Mám C kód /ne C++ kvůli školnímu projektu) a následující fragment kódu (nechce se mi tady dávat celý,ale když budete chtít, tak mohu, jinak neřešte prosím smysluplnost nebo jak by to šlo jinak, potřeboval bych spíše vysvětlit jednu věc):

Kód: [Vybrat]
for(i<0;i<pocet_nul;i++)
    {
      sprintf(radek, "0");
      fputs(radek,fp);
      fflush(fp);
    }

a

Kód: [Vybrat]
for(i<0;i<pocet_nul;i++)
    {
      fprintf(fp,"0");
    }

Problém je ten, že první kód se nechová stabilně - to znamená, že například z třiceti 0 mi zapíše do souboru jen 25. Navíc je zvláštní, že na Linuxu (Fedora 20) se to chová korektně, kdežto ve Windows nikoliv. Druhý kód dělá to co má. V obou dvou používám Code:Blocks s GCC.

Je něco, v čem bych si měl u fputs a fflush dávat pozor?
Název: Re:Zápis do souboru - fflush vs fprintf
Přispěvatel: Pali 25. 11. 2015, 15:25:48
Je něco, v čem bych si měl u fputs a fflush dávat pozor?

Nie u fputs, ale u sprintf. A to na pretečenie poľa radek. Doporučujem sprintf vôbec nepoužívať. Namiesto neho použiť snprintf.
Název: Re:Zápis do souboru - fflush vs fprintf
Přispěvatel: Meh 25. 11. 2015, 16:42:59
1. pouzivej parametry kompilatoru "-Wall" a "-Wextra"
2. pouzivej staticky analyzer, napr. CppCheck (podporovan v Code:Blocks)
3. inicializace for cyklu je divna "i<0", cyklus pak zalezi na predchozi hodnote "i"
   ("-Wall" vyhodi "warning: statement with no effect")

Zaver:
mas spatne inicializaci for cyklu - "i<0" misto "i=0"
Název: Re:Zápis do souboru - fflush vs fprintf
Přispěvatel: Withy14 26. 11. 2015, 12:22:59
1. pouzivej parametry kompilatoru "-Wall" a "-Wextra"
2. pouzivej staticky analyzer, napr. CppCheck (podporovan v Code:Blocks)
3. inicializace for cyklu je divna "i<0", cyklus pak zalezi na predchozi hodnote "i"
   ("-Wall" vyhodi "warning: statement with no effect")

Zaver:
mas spatne inicializaci for cyklu - "i<0" misto "i=0"

Ahoj, sry - chyba se vloudila :D má být i=0. Psal jsem to z hlavy.
Název: Re:Zápis do souboru - fflush vs fprintf
Přispěvatel: Withy14 26. 11. 2015, 12:26:50
Je něco, v čem bych si měl u fputs a fflush dávat pozor?

Nie u fputs, ale u sprintf. A to na pretečenie poľa radek. Doporučujem sprintf vôbec nepoužívať. Namiesto neho použiť snprintf.

Mám za to, že sprintf, tak jak mám napsaný, přetéct nemůže:
Kód: [Vybrat]
sprintf(radek, "0");
To mi do radku hodi vždy jeden znak, zkusím si to zdebugovat plus se podívám na ten snprintf, pokud mi to umožní čisté C.
Název: Re:Zápis do souboru - fflush vs fprintf
Přispěvatel: fsfsfsdf 26. 11. 2015, 12:37:40

Mám za to, že sprintf, tak jak mám napsaný, přetéct nemůže:
Kód: [Vybrat]
sprintf(radek, "0");
To mi do radku hodi vždy jeden znak, zkusím si to zdebugovat plus se podívám na ten snprintf, pokud mi to umožní čisté C.
[/quote]

Pokud ma promena radek vetsi delku jak 2 byte, tak by to melo byt ok:

char radek[2];

Název: Re:Zápis do souboru - fflush vs fprintf
Přispěvatel: Meh 26. 11. 2015, 19:08:45
Kazda z tech "stdio" funkci muze z nejakeho duvodu "selhat".
Chyba muze byt i mimo ten for cyklus (napr. jak zmineno vyse, deklarace u "radek").
Take muzes mit nejakou spatnou verzi mingw-gcc, nejake knihovny, ci neceho jineho.

Tedy, fputs a fflush pouzivas normalne.

Nize uvedeny kod mi na windows s mingw-gcc 4.4 funguje bez problemu (i bez overovani uspechu volani funkci).
Kód: [Vybrat]
int i;
char radek[2];
int pocet_nul = 30;
FILE *fp = fopen("test0.txt", "w");
if (fp == NULL)
    perror("Error: opening test0.txt failed");
else
    {
      for(i=0;i<pocet_nul;i++)
          {
            if (sprintf(radek, "0") != 1) printf("Error: sprintf failed");
            if (fputs(radek,fp) < 0) printf("Error: fputs failed\n");
            if (fflush(fp) != 0) printf("Error: fflush failed\n");
            if (ferror(fp)) printf("Error: something failed\n");
          }
      if (fclose (fp) != 0) printf("Error: fclose failed\n");
    }
Název: Re:Zápis do souboru - fflush vs fprintf
Přispěvatel: Withy14 27. 11. 2015, 15:51:02
Ahoj, dík všem za připomínky. Co se týče kódu od Meh, tak jsem ošetření/debugování až takhle nedělal, počítám s tím, že až dostanu ve škole úplné zadání, tak se tím zabývat budu - ale ošetření budu chtít mít na takové úrovni, že mi do cyklů a podmínek půjdou korektní data (klidně tady ten program pak nahodím). To neznamená, že bych nebyl vděčný za jakoukoliv připomínku. Momentálně si akorát chystám hlavičky s tím nejhorším, co asi v projektu bude (operace se soubory plus věci typu sscanf a podobně, abych to měl pak z krku).

Prostě takové "demo" (na základě projektů z předchozích let). Jediné co mi vadí, že to je prostě věc, která nebude v reálu použitelná, bavil jsem se  s učitelem a ten mi řekl, že není schopen při tolika studentech vymýšlet zadání, která by měla smysl, že takové věci se řeší právě až na bakalářce (prosím, žádný flame na téma vysoké školy).
Název: Re:Zápis do souboru - fflush vs fprintf
Přispěvatel: k 27. 11. 2015, 16:34:55
Jediné co mi vadí, že to je prostě věc, která nebude v reálu použitelná

Reálně použitelné z tohoto projektu jsou informace:
1) printf a spol dává na konec ještě znak 0x00, polopaticky jeden znak navíc.
2) Funkce bez kontroly délky jako třeba sprintf jsou deprecated a jsou nahrazeny snprintf atd.
3) fflush se používá jenom ve speciálních případech, jelikož již samo fclose obsahuje funkčnost fflush.