Ú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ě.