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 (11.díl) - Formátovaný výstup
27. listopadu 2000, 00.00 | I dnes bude řeč o i/o-funkcích, konrétně o prostředcích formátovaného
vstupu a výstupu.
Minule jsme se zabývali vstupně výstupními funkcemi, které dokázaly vypsat (nebo přečíst) jeden znak nebo řetězec znaků. Jazyk C ale nabízí i mnohem komplexnější nástroj, kterým je možné rovnou tisknout (nebo získat) i hodnoty jiných typů, a to bez nutnosti použití některé z konverzních funkcí.
Funkce formátovaného výstupu
int printf(char format[], ...)
Velice užitečnou funkcí je v jazyce C funkce printf, která slouží k formátovanému výstupu textu. Tato funkce je nadefinována s proměnným počtem parametrů, nicméně jeden argument má vždy. Je jím řetězec format, který funkce vypíše na standardní výstup.
printf("ahoj");
Přesnější by bylo říci, že vypíše všechny obyčejné znaky. Kromě těch může totiž řetězec obsahovat i tzv. popisovače. To jsou znakové posloupnosti, začínající znakem '%', pomocí kterých můžeme jednoduše vypisovat hodnoty výrazů, které jsou funkci printf předány v jejích dodatečných parametrech. Chceme-li například vypsat hodnotu intové proměnné i, bude zápis s použitím printf vypadat takhle:
int a=26; printf("hodnota a je: %i\n", a);
Provádění takto zapsaného voláni funkce printf vypadá následovně: Nejdříve se postupně čte řetězec format tak, že obyčejné znaky jsou hned posílány na výstup. Narazí-li se na znak popisovače '%',znamená to, že se na výstup pošle hodnota dalšího parametru printf (chceme-li vytisknout přímo znak procenta, musíme použít sekvenci '%%'). Podle znaku konverze (v našem případě je to znak 'i') se zjistí, jakého typu je hodnota parametru a podle toho je konvertována na řetězec, který se pošle na výstup. Pak se dále pokračuje ve čtení řetězce format. V našem příkladu zbývá ještě znak '\n', kterým odřádkujeme. Printf vrací počet skutečně zapsaných znaků, což je v našem případě 17.
Počet dodatečných parametrů je libovolný, a tak můžeme jedním voláním printf vypsat hodnoty třeba desíti výrazů. Je ale nutné dodržet několik zásad. Předně musí počet parametrů (bez povinného parametru format) přesně odpovídat počtu popisovačů v řetězci format. Každému popisovači odpovídá jeden skutečný parametr, a to v pořadí jak jsou zapsány. První výskyt popisovače je tedy svázán s druhým skutečným parametrem printf, druhý výskyt s třetím parametrem, atd. Druhou věcí, na kterou je třeba si dát pozor, jsou typy uvedené v popisovači. Ty musí skutečně odpovídat typům parametrů funkce, jinak se program může začít chovat podivně a nemusí pak být snadné tuto chybu odhalit.
Formátovaný vstup
int scanf(char format[], ...)
Opakem printf je funkce scanf, díky které je možné v jednom kroku načíst hodnotu do více proměnných, za předpokladu, že známe formát vstupních dat. Dejme tomu, že vyzveme uživatele našeho programu, aby zadal datum svého narození. Zároveň budeme chtít uložit vložená data do příslušných proměnných rok, mesic, den.
int den, mesic, rok; printf("zadej datum narozeni ve formatu (dd.mm.rrrr):"); scanf("%d:%d:%d", &den, &mesic, &rok);
Řetězec format může obsahovat tři typy znaků. Prvním jsou tzv. "bílé znaky", což je mezera, tabulátor '\t', nebo znak nového řádku '\n'. Narazí-li se při zpracovávání řetězce format na bílý znak, funkce na vstupu očekává libovolný počet (i 0) za sebou jdoucích bílých znaků, které všechny přečte, ale které nikam neukládá. Pokud se v řetězci format vyskytuje i nějaký obyčejný znak, funkce předpokládá stejný znak na vstupu. Ten opět přečte, ale neuloží. Pokud by přečtený znak neodpovídal předpokládanému, funkce se předčasně ukončí. Poslední, co může řetězec format obsahovat, a kvůli čemu to vlastně děláme, je znak '%', který uvozuje sekvenci popisovače, a který funguje stejně jako u funkce printf, s tím rozdílem, že načtená data se do proměnných, předaných dalšími parametry scanf, zapisují. Ve skutečnosti ale funkci nepředáváme přímo proměnné, ale pouze ukazatele na ně (to zařídí operátor '&' před identifikátorem proměnné). Jinak by nebylo možné do proměnných nic uložit, protože by funkce pracovala pouze s jejich lokálními kopiemi. Výjimkou je typ pole, pro který se lokální kopie nevytváří nikdy, a tak operátor & při ukládání do proměnné typu řetězec nepoužijeme.
Načítání do řetězce pomocí scanf je ovšem poněkud zrádnou záležitostí, protože není možné načíst řetězec obsahující mezeru. První bílý znak, na který se narazí při načítání do proměnné je chápán jako konec celého řetězce. Tento bílý znak už načtenému řetězci nenáleží, a je tedy dál zpracováván normálním způsobem. Ostatně, i celé použití scanf může být zrádné, protože pokud data, která funkce získává, nebudou v předem očekávaném formátu, předčasně se ukončí. Čtení dat zadaných uživatelem našeho programu pomocí scanf je pak vyloženě riskantní záležitostí. :) Naštěstí scanf vrací počet úspěšně načtených zkonvertovaných a přiřazených hodnot. Pokud však funkce při prvním pokusu o načtení znaku narazí na EOF nebo EOS (end of string), vrací hodnotu EOF (end of file).
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
Diskuse k článku
-
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