Toto je najčastejšie diskutovanou témou, plný názor, ale zaujímavé žiadny menej. Som pozoroval, že veľká väčšina z tých, ktoré už odpovedal na podobné otázky, na tejto stránke pokles na strane fgets()
. Ja som jeden z nich. Zistil som, fgets()
byť oveľa lepšie použiť na vstup používateľa, ako scanf()
s niekoľkými výnimkami. scanf()
je zvažoval veľa ako sub-optimálne metódy pre manipuláciu vstupu používateľa. Napríklad
"...to vám povie, či je to podarilo alebo nepodarilo, ale môžu vám povedať len približne kde sa to nepodarilo, a nie na všetky, ako a prečo. Ste
majú veľmi malú možnosť urobiť žiadnu chybu obnovy."
(jamesdlin). Ale v záujme pokus rovnováhu, začať citovať túto diskusiu.
Pre vstup užívateľa, ktorý pochádza z stdin
, t. j. vstup z klávesnice, fgets()
bude lepšou voľbou. To je oveľa viac priestoru v tom, že reťazec je číta môže byť plne potvrdené pred konverzie je pokus
Jeden z mála okamihov, na formulári scanf(): fscanf() bude v poriadku použitie môže byť pri prevode textu z veľmi riadený zdroj, t. j. z čítania prísne formátovaný súbor s opakovaním predvídateľné polia.
Pre ďalšie diskusie, toto porovnanie dvoch vrcholov ďalšie výhody a nevýhody oboch.
Edit: na adresu OP ďalšie otázky o pretečeniu:
"Jedna vec, ktorú chcem sa opýtať je: aj keď používame fgets čo sa stane, ak používateľ zadať viac znakov, než je hranica (mám na mysli veľa
znaky), to viesť k pretečenie medzipamäte? Potom, ako sa vysporiadať s
to?"
[fgets()](https://www.tutorialspoint.com/c_standard_library/c_function_fgets.htm je pekne navrhnutý tak, aby sa zabránilo buffer pretečeniu, jednoducho pomocou jeho parametre správne, napr.:
char buffer[100] = {0};
...
while fgets(buffer, sizeof buffer, stdin);
To zabraňuje vstupu väčšia ako veľkosť buffra zo spracovania, a tým predchádzať pretečeniu.
dokonca aj použitie scanf()
prevencia pretečenie medzipamäte je docela rovno vpred: Použitie šírka špecifikátor v formátovací reťazec. Ak si chcete prečítať vstup pre príklad a obmedziť vstup veľkosť od užívateľa do 100 znakov max., kód bude obsahovať nasledujúce:
char buffer[101] = {0};// includes space for 100 + 1 for NULL termination
scanf("%100s", buffer);
^^^ width specifier
Avšak s číslami, pretečenie nie je tak pekné pomocou scanf()
. Preukázať, použite tento jednoduchý kód, zadanie dve hodnoty uvedené v jeden komentár na spustenie:
int main(void)
{
int val = 0;
// test with 2147483647 & 2147483648
scanf("%d", &val);
printf("%d\n", val);
return 0;
}
Pre druhú hodnotu, môj systém hodí takto:
NON-FATAL RUN-TIME ERROR: "test.c", line 11, col 5, thread id 22832: Function scanf: (errno == 34 [0x22]). Range error
`
Tu je potrebné, aby si v reťazec, potom postupujte podľa reťazec na číslo konverzie pomocou jedného z strto_()
funkcie: strtol(), strtod(), ...). Obe zahŕňajú schopnosť test pre pretečeniu pred spôsobuje run-time varovanie alebo chyba. Všimnite si, že pomocou atoi()
, atod()
nebude chrániť pred prepadom buď.