Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!
Zadejte Vaši e-mailovou adresu:
Kamarád fotí rád?
Přihlas ho k odběru fotomagazínu!
Zadejte e-mailovou adresu kamaráda:
C/C++
Učíme se C (10.díl) - Vstupně výstupní funkce
14. listopadu 2000, 00.00 | Znakově a řetězcově orientované vstupně-výstupní funkce pracující
se standardním vstupem a výstupem.
Dnes se budeme zabývat vstupně výstupními funkcemi, ale než se tak stane, dovolte mi ještě odbočit a vrátit se o něco zpět. Ačkoliv jsem již používal tzv. escape-sekvence, dosud jsem blíže nevysvětlil, o co vlastně jde. V jazyce C totiž existuje kromě normálního způsobu zápisu znaků ('a', '2' atd.) ještě jeden, pomocí něhož často zapisujeme ty znaky, které nelze zapsat normálním způsobem. Jsou to například znaky odřádkování, tabulátor. V řetězcových konstantách zase nelze normálně zapsat znak " apod. Proto jazyk C zavádí ještě tzv. escape-sekvence. To je kombinace zpětného lomítka a nějakého určitého znaku, která dohromady představuje jeden znak. Např. dvojice \n představuje znak odřádkování, \t zase tabulátor, escape sekvencí \" zapíšeme znak uvozovek a \\ představuje jedno zpětné lomítko. Je také možné použít zápisu s číslem, který pak bude představovat znak s ascii hodnotou tohoto čísla. Např. '\27' představuje znak escape, jehož ascii hodnota je 27. Chtěli-li bychom vytvořit řetězcovou konstantu obsahující: Napsal: "Je to v c:\adr", udělali bychom to takto:
"Napsal: \"Je to v c:\\adr\""
A teď už k dnešnímu tématu. Funkcí, které zajišťují vstup a výstup dat, existuje v jazyce C mnoho. Dnes se budeme zabývat těmi, které se používají pro vstup (resp. výstup) tzv. standardní vstup-stdin (resp. standardní výstup-stdout).
Standardní vstup a výstup
S pojmy standardní vstup/výstup jste se již pravděpodobně setkali, pokud ale ne, zde je krátké vysvětlení. Standardní vstup a výstup jsou vlastně jakési abstrakce vstupního a výstupního zařízení. Standardní vstup nejčastěji představuje klávesnici a standardní výstup zase monitor. Operační systém pak nabízí prostředky, pomocí kterých je možné změnit standardní vstupně-výstupní zařízení, a tak například přesměrovat výstup programu do souboru. Stejně tak je možné v rámci OS předat programu jako vstup soubor.
Následující řádky se budou zabývat funkcemi, které provádějí výstup dat na standardní výstup, nebo které čtou data ze standardního vstupu.
Výstup znaku
int putchar(int c)
Pro výstup jednoho znaku nám poslouží funkce putchar, která na standardní výstup pošle znak, jehož ascii hodnota byla funkci předána parametrem c. V případě, že je standardním výstupem monitor, znak se vypíše na aktuální pozici na obrazovku. Jestliže se celá operace podařila, vrací putchar hodnotu tištěného znaku, v opačném případě vrací hodnotu EOF (end of file). Symbolická hodnota EOF bývá definována jako záporné číslo, a proto, pokud budete návratovou hodnotu uchovávat, používejte výhradně proměnnou typu int.
Vstup znaku
int getchar(void)
Funkce getchar přečte jeden znak ze standardního vstupu (nejčastěji klávesnice) a vrátí jeho ascii hodnotu pomocí typu int. Slovo void v závorkách značí, že funkce nemá žádný parametr. Pokud je standardním vstupem klávesnice, pak je vstup bufferovaný po řádcích, což znamená, že dříve než se provede samotná funkce getchar, jsou do klávesnicového bufferu načítány znaky tak dlouho, dokud není stištěna klávesa enter. Podívejme se na následující příklad:
int c; c = getchar(); putchar(c); c = getchar(); putchar(c);
Nejdříve se musí provést první příkaz getchar, který bude čekat na vstup od uživatele. Stiskneme-li ale např. klávesu 'a', vykonávání getchar tím nekončí, protože zatím se jenom znak 'a' zapsal do bufferu. Znak se také automaticky vypíše na obrazovku. I další vložené znaky se budou zapisovat do bufferu, a to tak dlouho, dokud uživatel nestiskne enter. Předpokládejme tedy, že jsme napsali slovo "ahoj" a odřádkovali. Pak se konečně do proměnné c uloží první stištěný znak, v našem případě tedy 'a'. Následující příkaz putchar pak tento znak vytiskne na obrazovku. Pokud budeme znovu volat getchar, již se nečeká na další vstup uživatele, protože v klávesnicovém bufferu jsou dosud navybrané znaky z minulého volání getchar ('h' + 'o' + 'j' + '\n'). Proto je ihned vybrán další znak, tedy 'h'. Abychom buffer vyprázdnili, museli bychom číst pomocí getchar ještě třikrát. Nesmíme totiž zapomenout na znak odřádkování - '\n'.
Následující příklad předvádí část programu, který ze standardního vstupu přečte jednu řádku textu, tu uloží do řetězce str a následně tento řetězec vypíše na standardní výstup. Program troufale předpokládá, že vstup nebude delší jak 300 znaků.
int c=0; char str[301]; //načtení řádku textu do str c=getchar(); while(c != '\n') { str[i]=c; i++; c=getchar(); } str[i]='\0'; //výpis obsahu str for (i=0; i<strlen(str); i++) putchar(str[i]);
Řetězcový výstup
int puts(char string[])
Funkce puts jednoduše vypíše na standardní výstup celý řetězec předaný jí parametrem string a po jeho vypsání automaticky odřádkuje. Při úspěchu funkce vrací nezápornou hodnotu. V případě, že se nepodařilo řetězec vytisknout (např. při přesměrování do souboru, pro který už není na disku dostatek místa), vrací funkce hodnotu EOF.
Řetězcový vstup
char *gets(char buffer[])
Opakem předchozí funkce je funkce gets, která čte znaky ze standardního vstupu a ukládá je do předaného řetězce buffer tak dlouho, dokud nenarazí na znak odřádkování '\n'. Ten už do řetězce buffer neuloží!!! Jako poslední vloží funkce gets znak EOS, a pak už jen vrátí ukazatel na buffer. Pokud by nebyl vložen žádný znak, funkce vrací nulový pointer NULL.
Funkce gets je nebezpečná v tom, že předem nevíme kolik znaků se do proměnné buffer zapíše, a proto se může stát, že velikost bufferu nebude dostatečná. Tato nepříjemnost, která dělá funkci gets prakticky nepoužitelnou, se však dá obejít použitím funkce fgets, o které bude řeč v některém z dalších dílů.
Výše zapsaný program čtoucí jednu řádku ze vstupu lze za pomoci funkcí gets a puts zapsat takto:
char str[301]; gets(str); puts(str);
Obsah seriálu (více o seriálu):
- Učíme se C (1. díl)
- Učíme se C (2. díl)
- Učíme se C (3.díl)
- Učíme se C (4. díl)
- Učíme se C (5.díl)
- Učíme se C (6.díl)
- Učíme se C (7.díl)
- Učíme se C (8.díl)
- Učíme se C (9.díl) - Řetězce
- Učíme se C (10.díl) - Vstupně výstupní funkce
- Učíme se C (11.díl) - Formátovaný výstup
- Učíme se C (12.díl) - Formátový specifikátor
- Učíme se C (13.díl)
- Učíme se C (14.díl) - Vícerozměrná pole
- Učíme se C (15.díl) - Ukazatele
- Učíme se C (16.díl) - Modifikátory paměťové třídy
- Učíme se C (17.díl) - Pole a ukazatel
- Učíme se C (18. díl) - Dynamická alokace paměti
- Učíme se C (19. díl) - Práce se soubory I.
- Učíme se C (20. díl) - Práce se soubory II.
- Učíme se C (21. díl) - Parametry funkce main()
- Učíme se C (22. díl) - Ukazatele na funkce
- Učíme se C (23. díl) - Složité deklarace a definice
- Učíme se C (24. díl) - Funkce s proměnným počtem parametrů
- Učíme se C (25. díl) - Bitové operátory a bitové pole
- Učíme se C (26. díl) - Datové typy enum a union
- Učíme se C (27. díl - závěr) - Programové moduly
-
25. listopadu 2012
-
30. srpna 2002
-
10. října 2002
-
4. listopadu 2002
-
12. září 2002
-
25. listopadu 2012
-
28. července 1998
-
31. července 1998
-
28. srpna 1998
-
6. prosince 2000
-
27. prosince 2007
-
4. května 2007