Úvod
Funkce fgets()
a gets()
slouží v programovacím jazyce C k načítání řetězců ze vstupního proudu. Přestože obě tyto funkce plní podobný účel, existují mezi nimi zásadní rozdíly. V tomto článku si tyto funkce podrobně probereme, včetně jejich odlišností, výhod a nevýhod. To vám pomůže rozhodnout, kterou z nich zvolit pro konkrétní situaci.
fgets()
Funkce fgets()
načítá řádek ze vstupního proudu a ukládá ho do zadané paměti (bufferu). Funkce vyžaduje tři argumenty:
- Ukazatel na buffer, do kterého se bude řetězec ukládat.
- Maximální počet znaků, které se mají načíst.
- Vstupní proud (např. standardní vstup stdin).
Příklad použití:
char buffer[100];
fgets(buffer, 100, stdin);
V uvedeném příkladu funkce fgets()
načte řádek ze standardního vstupu (stdin) a uloží ho do bufferu buffer
, který má velikost 100 znaků. Funkce vrací ukazatel na buffer, nebo NULL
v případě chyby.
gets()
Funkce gets()
se podobá funkci fgets()
, ale má několik klíčových rozdílů:
- Nepřijímá argument pro maximální počet znaků.
- Načítá celý řádek až do konce řádku nebo do konce souboru.
- Nepřidává ukončovací znak
'\0'
na konec řetězce.
Příklad použití:
char buffer[100];
gets(buffer);
V tomto příkladu gets()
načítá řádek ze standardního vstupu a ukládá ho do buffer
o velikosti 100 znaků. Funkce však sama o sobě nepřidává ukončovací znak '\0'
. Proto buffer může obsahovat „odpadní data“ za samotným řetězcem.
Rozdíly mezi fgets() a gets()
Hlavním rozdílem mezi fgets()
a gets()
je způsob zpracování ukončovacího znaku '\0'
. Funkce fgets()
ho automaticky přidává na konec načteného řetězce, zatímco gets()
nikoliv. Toto může vést k problémům, pokud s tím nepočítáte při práci s výsledkem funkce gets()
.
Dalším zásadním rozdílem je, že fgets()
akceptuje maximální počet znaků jako argument, zatímco gets()
nikoliv. To znamená, že při použití gets()
může dojít k přetečení bufferu, pokud neznáte přesnou délku načítaného řetězce.
Výhody a nevýhody
fgets()
- Výhody:
- Automaticky přidává ukončovací znak
'\0'
. - Omezuje počet načtených znaků, čímž předchází přetečení bufferu.
- Nevýhody:
- Může být pomalejší než
gets()
pro velmi dlouhé řetězce.
gets()
- Výhody:
- Pro dlouhé řetězce je rychlejší než
fgets()
. - Nevýhody:
- Nepřidává ukončovací znak
'\0'
. - Může vést k přetečení bufferu, pokud je načítaný řetězec delší než buffer.
Kdy použít fgets()
Použijte fgets()
v situacích, kdy:
- Potřebujete řetězec s ukončovacím znakem
'\0'
. - Znáte maximální délku řetězce, který chcete načíst.
- Chcete zabránit přetečení bufferu.
Kdy použít gets()
Použijte gets()
v situacích, kdy:
- Nechcete automatické přidání ukončovacího znaku
'\0'
. - Neznáte maximální délku načítaného řetězce.
- Potřebujete co nejvyšší výkon při načítání velmi dlouhých řetězců.
Závěr
Funkce fgets()
a gets()
jsou v jazyce C užitečnými nástroji pro načítání řetězců. Přestože se jejich účel zdá být stejný, existují mezi nimi důležité rozdíly. Volba té správné funkce závisí na konkrétních požadavcích. Pokud požadujete ukončovací znak a znáte maximální délku, použijte fgets()
. Jestliže potřebujete maximální rychlost pro dlouhé řetězce, nebo vám ukončovací znak nevadí, můžete použít gets()
. Je však potřeba pamatovat na rizika s ní spojená.
Často kladené otázky
- Která funkce je rychlejší:
fgets()
nebogets()
?Většinou je
gets()
rychlejší pro velmi dlouhé řetězce, zatímcofgets()
je rychlejší pro krátké řetězce. - Kdy použít funkci
scanf()
namístofgets()
nebogets()
?Funkci
scanf()
použijte v případě, že chcete načíst řetězec a zároveň ho konvertovat na jiný datový typ, například číslo. - Je možné zabránit přetečení bufferu při používání funkce
gets()
?Ano, je možné použít funkci
strncat()
společně sgets()
a omezit tak počet načtených znaků. - Jak zpracovat řetězec načtený pomocí
gets()
tak, aby obsahoval ukončovací znak?Můžete použít funkci
strcat()
pro přidání ukončovacího znaku na konec řetězce. - Kterou funkci použít při načítání řetězce ze souboru?
Při čtení ze souboru je obvykle lepší použít funkci
fgets()
, protože automaticky přidává ukončovací znak a předchází přetečení bufferu. - Kterou funkci použít při načítání řetězce z konzole?
Pro načítání řetězce z konzole můžete použít jak
fgets()
, takgets()
. Nicméněfgets()
je preferována, protože přidává ukončovací znak a předchází přetečení bufferu. - Co se stane, pokud
fgets()
nebogets()
narazí na konec souboru?V případě, že funkce
fgets()
nebogets()
dosáhnou konce souboru, vrátí hodnotuNULL
. - Jak ošetřit chybu při používání funkcí
fgets()
nebogets()
?Můžete zkontrolovat návratovou hodnotu funkce. Pokud je
NULL
, došlo k chybě.