Vstup a výstup v jazyce C
Author
Albert FloresVstup a výstup v jazyce C je v informatice řešen souborem knihovních funkcí ze standardní knihovny jazyka C (libc, glibc a podobně), jejíž prototypy jsou deklarovány v hlavičkovém souboru . Programovací jazyk C při operacích vstupu a výstupu využívá proudy bytů a nerozlišuje mezi vstupními a výstupními zařízeními, rourami a soubory, přičemž definuje standardní proudy (stdin, stdout a stderr).
Proudy
Na rozdíl od některých dřívějších programovacích jazyků, nemá jazyk C přímou podporu pro přímý přístup k datům souborů. Pro čtení uprostřed souboru musí programátor nejprve vytvořit proud, ve kterém pak pomocí funkce fseek nastaví ukazatel do místa v souboru, ze kterého následně bude číst nebo zapisovat.
Použití proudů pro práci se soubory bylo zpopularizováno operačním systémem UNIX, který byl vyvíjen ve stejné době, jako programovací jazyk C. Celá řada moderních operačních systémů proudy z unixových systémů zdědila stejně, jako je mnoho programovacích jazyků zdědilo z jazyka C (např. +more PHP). Též do standardních knihoven jazyka C++ se promítají proudy (tzv. iostream).
Otevírání souboru
Soubor je otevírán použitím funkce fopen, která vrací I/O proud. Ten je připojen k danému souboru nebo jinému blokovému zařízení umožňujícímu operace čtení a zápis. +more V případě, že funkce selže, vrací nulový ukazatel (NULL). Související knihovní funkce freopen vykonává stejnou operaci, avšak nejprve zavře otevřený proud, který je uveden jako doplňující parametr.
I/O proud je definován takto:
FILE *fopen(const char *path, const char *mode); FILE *freopen(const char *path, const char *mode, FILE *fp);
Funkce fopen je wrapper, který na vyšší úrovni obaluje jednoduché systémové volání open jádra unixového operačního systému. Stejným způsobem jako fopen pracuje i funkce fclose, která poskytuje obálku pro systémové volání jádra close. +more Struktura FILE jazyka C se velmi často shoduje se souborovými deskriptory používanými v unixových systémech. V POSIXu je definována funkce fdopen, která inicializuje I/O proud z existujícího deskriptoru, přestože deskriptory jsou čistě unixová záležitost a nejsou obsaženy ve standardech jazyka C.
Parametr mode, který využívají funkce fopen nebo freopen, musí být řetězec začínající jednou z následujících sekvencí či jejich kombinací:
mode | popis | ukazatel na | ||
---|---|---|---|---|
r | rb | otevření pro čtení | začátku souboru | |
w | wb | otevření pro zápis: pokud soubor neexistuje, vytvoří ho; pokud soubor již existuje, vymaže obsah a zapíše data | začátku souboru | |
a | ab | připojení dat: nová data jsou zapisována na konec souboru, ke změně existujících dat nedojde (pokud soubor neexistuje, vytvoří ho) | konci souboru | |
r+ | rb+ | r+b | otevření pro čtení a zápis | začátku souboru |
w+ | wb+ | w+b | otevření pro čtení a zápis. Vymaže obsah a přepíše soubor. +more | začátku souboru |
a+ | ab+ | a+b | otevření pro čtení a zápis (pokud soubor existuje, jsou nová data zapisována na konec souboru) | konci souboru |
Označení „b“ znamená binární. Standardy jazyka C poskytují dva typy souborů - textové a binární, ačkoli operační systém nemusí být schopen je rozlišovat.
Textový soubor: V režimu textového souboru je text uspořádán v řádcích, jejichž konce jsou označeny znakem nového řádku (zkratka EOL). Unixové systémy označují nový řádek znakem LF, zatímco DOS a Microsoft Windows používají kombinaci CR/LF. +more Při čtení z textového souboru je obvykle mapována sekvence EOL na znak LF, což slouží ke zjednodušení zpracování v programu. V případě, že je textový soubor zapisován, převádí se před vlastním zápisem EOL automaticky na znaky, které daný operační systém používá.
Binární soubor: V režimu binárního souboru je obsah souboru čten a zapisován operačním systémem bez úprav (obsah je doručen programu bez automatického převodu, tzv. přímý přístup).
Znak „+“ (režim aktualizace): Když je soubor otevřen v režimu aktualizace (znak „+“ na druhé nebo třetí pozici), může být na daném proudu použito čtení i zápis, avšak je-li po operaci zápisu nemůže být volána funkce čtení bez toho, aby mezi nimi byla volána funkce fflush nebo funkce pro změnu pozice ukazatele (fseek, fsetpos nebo rewind). Stejně tak čtení nemůže být následováno zápisem bez toho, aby mezi nimi byla též volána funkce pro změnu pozice ukazatele.
Automatické vytvoření souboru: Pokud při volání funkce otevření souboru v režimu zápisu nebo připojení za konec souboru požadované jméno neexistuje, pokusí se funkce soubor požadovaného jména vytvořit. Pokud operace selže, vrací se hodnotu NULL.
Uzavření proudu
Funkce fclose pracuje pouze s jedním argumentem, a to s ukazatelem na souborovou strukturu proudu určeného k zavření. Po zavření se uvolní paměť vyhrazená pro strukturu FILE * a vyprázdní se vyrovnávací paměť. +more Bez opětovného otevření proudu již není práce se souborem možná. Počet otevřených souborů je omezen, proto jestliže se souborem nebudeme již pracovat, měli bychom jej uzavřít. Uzavření souboru je prováděno příkazem:.
int fclose(FILE *fp);
Pokud proud neuzavřeme pomocí příkazu, uzavře se sám po ukončení programu. Při úspěšném uzavření souboru vrací funkce hodnotu 0, při selhání vrací EOF.
Čtení z proudu
Pro načtení znaku z proudu se používá funkce fgetc:
int fgetc(FILE *fp);
Když je volání úspěšné, fgetc načte další byte nebo znak z proudu (záleží na tom, zda je soubor binární nebo textový). V případě, že volání úspěšné není fgetc vrací EOF (specifický typ chyby může být určen podle systémového volání ferror nebo feof s ukazatelem na soubor). +more Standardní makro getc, které je také definováno v , se chová obdobně jako fgetc. Krom toho může samo o sobě vyhodnocovat opakovaně své argumenty.
Standardní funkce getchar je také definována v , nepodporuje práci s argumenty a je ekvivalentní k getc(stdin). Pro blokové čtení ze souboru se používá funkce fread, která načte ze zadaného proudu n položek o určené velikosti a ukládá je do paměti označené ukazatelem. +more Návratovou hodnotou této funkce je počet skutečně přečtených položek.
Zápis do souboru
Pro zápis do souboru využíváme funkce putc, fprintf:
int putc(int c, FILE *file); int fprintf(FILE *file, char *format, …);
U všech funkcí pro zápis do souboru platí, že se pozice ukazatele posune za poslední zapsaný byte v souboru. Pro blokový zápis se využívá funkce fwrite, která zapíše do proudu n položek načtených z paměti. +more Tato funkce vrací zpět počet úspěšně zapsaných položek, nikoliv bytů.
Přehled funkcí
Většina vstupně/výstupních funkcí jazyka C je definována v stdio.h (cstdio hlavička v C++).
Byte znak | Šířka znak | Popis | |
---|---|---|---|
Přístup k souborům | [url=http://en. cppreference. +morecom/w/c/io/fopen]fopen[/url] | [url=http://en. cppreference. com/w/c/io/fopen]fopen[/url] | otevře soubor |
Přístup k souborům | [url=http://en. cppreference. com/w/c/io/freopen]freopen[/url] | [url=http://en. cppreference. com/w/c/io/freopen]freopen[/url] | otevře jiný soubor v existujícím proudu |
Přístup k souborům | [url=http://en. cppreference. com/w/c/io/fflush]fflush[/url] | [url=http://en. cppreference. com/w/c/io/fflush]fflush[/url] | synchronizuje výstupní proud s aktuálním souborem |
Přístup k souborům | [url=http://en. cppreference. com/w/c/io/fclose]fclose[/url] | [url=http://en. cppreference. com/w/c/io/fclose]fclose[/url] | uzavře soubor |
Přístup k souborům | [url=http://en. cppreference. com/w/c/io/setbuf]setbuf[/url] | [url=http://en. cppreference. com/w/c/io/setbuf]setbuf[/url] | nastaví buffer pro datový proud |
Přístup k souborům | [url=http://en. cppreference. com/w/c/io/setvbuf]setvbuf[/url] | [url=http://en. cppreference. com/w/c/io/setvbuf]setvbuf[/url] | nastaví buffer a jeho velikost pro datový proud |
Přístup k souborům | [url=http://en. cppreference. com/w/c/io/fwide]fwide[/url] | [url=http://en. cppreference. com/w/c/io/fwide]fwide[/url] | přepne datový proud mezi širokým znakem a úzkým znakem |
Přímý vstup/výstup | [url=http://en. cppreference. com/w/c/io/fread]fread[/url] | [url=http://en. cppreference. com/w/c/io/fread]fread[/url] | čte ze souboru |
Přímý vstup/výstup | [url=http://en. cppreference. com/w/c/io/fwrite]fwrite[/url] | [url=http://en. cppreference. com/w/c/io/fwrite]fwrite[/url] | zapisuje do souboru |
Neformátovaný vstup/výstup | [url=http://en. cppreference. com/w/c/io/fgetc]fgetc[/url] [url=http://en. cppreference. com/w/c/io/getc]getc[/url] | [url=http://en. cppreference. com/w/c/io/fgetwc]fgetwc[/url] [url=http://en. cppreference. com/w/c/io/getwc]getwc[/url] | čte byte/wchar_t z datového proudu |
Neformátovaný vstup/výstup | [url=http://en. cppreference. com/w/c/io/fgets]fgets[/url] | [url=http://en. cppreference. com/w/c/io/fgetws]fgetws[/url] | čte byte/wchar_t řádek z datového proudu |
Neformátovaný vstup/výstup | [url=http://en. cppreference. com/w/c/io/fputc]fputc[/url] [url=http://en. cppreference. com/w/c/io/putc]putc[/url] | [url=http://en. cppreference. com/w/c/io/fputwc]fputwc[/url] [url=http://en. cppreference. com/w/c/io/putwc]putwc[/url] | zapisuje byte/wchar_t do datového proudu |
Neformátovaný vstup/výstup | [url=http://en. cppreference. com/w/c/io/fputs]fputs[/url] | [url=http://en. cppreference. com/w/c/io/fputws]fputws[/url] | zapisuje byte/wchar_t řetězec do datového proudu |
Neformátovaný vstup/výstup | [url=http://en. cppreference. com/w/c/io/getchar]getchar[/url] | [url=http://en. cppreference. com/w/c/io/getwchar]getwchar[/url] | čte byte/wchar_t ze stdin |
Neformátovaný vstup/výstup | [url=http://en. cppreference. com/w/c/io/gets]gets[/url] | N/A | čte řetězec bytů ze stdin (nepoužívá v C99, zastaralé v C11) |
Neformátovaný vstup/výstup | [url=http://en. cppreference. com/w/c/io/putchar]putchar[/url] | [url=http://en. cppreference. com/w/c/io/putwchar]putwchar[/url] | zapíše byte/wchar_t na stdout |
Neformátovaný vstup/výstup | [url=http://en. cppreference. com/w/c/io/puts]puts[/url] | N/A | zapíše řetězec bytů na stdout |
Neformátovaný vstup/výstup | [url=http://en. cppreference. com/w/c/io/ungetc]ungetc[/url] | [url=http://en. cppreference. com/w/c/io/ungetwc]ungetwc[/url] | vloží byte/wchar_t zpět do datového proudu |
Formátovaný vstup/výstup | [url=http://en. cppreference. com/w/c/io/scanf]scanf[/url] [url=http://en. cppreference. com/w/c/io/fscanf]fscanf[/url] [url=http://en. cppreference. com/w/c/io/sscanf]sscanf[/url] | [url=http://en. cppreference. com/w/c/io/wscanf]wscanf[/url] [url=http://en. cppreference. com/w/c/io/fwscanf]fwscanf[/url] [url=http://en. cppreference. com/w/c/io/swscanf]swscanf[/url] | čte formátovaný byte/wchar_t vstup z stdin, datový proud nebo buffer |
Formátovaný vstup/výstup | [url=http://en. cppreference. com/w/c/io/vscanf]vscanf[/url] [url=http://en. cppreference. com/w/c/io/vfscanf]vfscanf[/url] [url=http://en. cppreference. com/w/c/io/vsscanf]vsscanf[/url] | [url=http://en. cppreference. com/w/c/io/vwscanf]vwscanf[/url] [url=http://en. cppreference. com/w/c/io/vfwscanf]vfwscanf[/url] [url=http://en. cppreference. com/w/c/io/vswscanf]vswscanf[/url] | čte formátovaný vstup byte/wchar_t ze stdin, datového proudu nebo bufferu pomocí proměnného seznamu parametrů |
Formátovaný vstup/výstup | [url=http://en. cppreference.
ReferenceExterní odkazy[url=://linux. die. +morenet/man/3/fclose - [[Manuálové stránky (Unix)|manuálová stránka]url=://linux. die. net/man/3/fgetc - [[Manuálové stránky (Unix)|manuálová stránka]url=://linux. die. net/man/3/fopen - [[Manuálové stránky (Unix)|manuálová stránka]url=://linux. die. net/man/3/fputc - [[Manuálové stránky (Unix)|manuálová stránka]url=http://code-reference. com/c/stdio. h]stdio. h on Coding Programmer Page / C Library Reference and Examples[/url] (en) *[/url]] pro Linux *[/url]] pro Linux *[/url]] pro Linux *[/url]] pro Linux * [url=http://c-faq. com/stdio/getcharc. html]Question 12. 1[/url] in the C FAQ: using char to hold getc's return value * [url=https://web. archive. org/web/20090207193504/http://www. koders. com/c/fid4AC8E5A6CAFCF1D081122F3CA5866F8ADCA5D1C4. aspx]Zdrojový kód[/url]. |