6 Štandardný vstup a výstup
Prostriedky pre vstup a výstup (so štandardnými zariadeniami - klávesnica a obrazovka, i so súbormi) nie sú priamou súčasťou C jazyka, ale sú poskytované vo forme štandardných knižníc, t.j. include súborov. Označenie štandardných zariadení pre vstup a výstup : stdin pre vstup, stdout pre výstup a stderr pre výstup chybových správ.
6.1 Vstupno-výstupná komunikácia
Vstupno - výstupná komunikácia sa môže uskutočňovať na troch úrovniach :
- znakov
- reťazcov
- formátovaných hodnôt
- Úroveň práce so znakmi je podporovaná dvoma funkciami :
int getchar(void) pre vstup znaku int putchar(int) pre výstup znaku
Funkcia getchar nemá argument a vracia ako hodnotu kódovú reprezentáciu znaku, ktorý bol na vstupe (stdin). Ak na stdin sa nenachádza žiadny znak (koniec súboru), getchar vráti hodnotu EOF.
Funkcia putchar má argument typu int, ktorý sa zapíše do výstupu stdout. Ako hodnotu vracia zapísaný znak, ak zápis prebehol normálne, inak vracia EOF (pri chybe počas výstupu).
- Úroveň práce s reťazcami je tiež podporovaná dvoma funkciami :
char *gets(char *string); int puts(char *string);
Funkcia gets slúži pre vstup reťazca do premennej string zo vstupu stdin, funkcia puts naopak pre výstup reťazca string na výstup stdout. Funkcia puts pridáva k výstupnému reťazcu nový riadok. Vracia nulu, ak nie je chyba, inak EOF.
- Úroveň formátovaných hodnôt - formátovaný vstup - výstup je tiež podporovaná dvoma štandardnými funkciami :
int printf(const char *format,arg1,...,argn); int scanf(const char *format,&arg1,...,&argn);
Tieto funkcie umožňujú výstup, resp. vstup údajov v predpísanom tvare. Počet výstupných (vstupných) údajov (t.j. argumentov funkcií print, scanf) je voliteľný, je možný aj počet n = 0. V prípade výstupu stačí uvádzať argumenty vo forme jednoduchých identifikátorov, resp. konštánt.
Pokiaľ sa jedná o vstup, všimnime si, že funkcie scanf vyžaduje zadanie adries jednotlivých argumentov (znak &). V prípade nedodržania tohoto požiadavku vznikajú nepríjemné chyby.
Funkcia printf vracia počet vytlačených znakov, resp. záporné číslo pri chybe.
Tieto funkcie vracajú počet vykonaných formátových konverzií. Spracovanie je ukončené pri výskyte prvého konfliktného znaku alebo konca súboru EOF, vracajú EOF ak nastane chyba na vstupe pred vykonaním formátovej konverzie. Predpísaný tvar výstupu jednotlivých argumentov obsahuje reťazec format. V tomto reťazci sa okrem znakov (textu), ktorý sa automaticky okopíruje na výstup, musí nachádzať pre každý argument jedna tzv. formátová konverzia, ktorá obsahuje konkrétny predpis pre prevod hodnoty argumentu z vnútorného (binárneho) tvaru na požadovaný vonkajší tvar. Každá formátová konverzia sa povinne začína znakom %, po ktorom nasleduje vlastný popis konverzie. Všetky znaky, ktoré nepatria do formátovej konverzie, sa kopírujú na výstup. Popis konverzie (jednotlivé parametre sa uvádzajú bez medzier, hranaté zátvorky znamenajú voliteľné použitie) má obecný tvar :
%[príznak][šírka][.presnosť][modifikátor]konverzia
pričom zložky popisu konverzie možno rozdeliť na povinné a nepovinné. Samotná konverzia je vždy povinná, ostatné zložky sú nepovinné. Význam jednotlivých zložiek je tento :
- Povinné:
celé čísla: %d celé dekadické číslo typu signed int %i celé dekadické číslo typu signed int %u celé dekadické číslo typu unsigned int %o celé oktálové číslo typu unsigned int %x celé hexadecimálne číslo typu unsigned int (malé písmo) %X celé hexadecimálne číslo typu unsigned int (veľké písmo) čísla v pohyblivej rádovej čiarke: %f číslo v desatinnom tvare typu float i double %e číslo v semilogaritmickom tvare typu float i double %E číslo v semilogaritmickom tvare typu float i double (s veľkým E) %g použije sa jedna z konverzií f, e. Výstupný tvar sa volí podľa hodnoty exponentu (ak je menší ako -4 alebo väčší ako presnosť, použije sa e, inak f) %G ako konverzia g, len sa použije konverzia E znaky a reťazce: %c jeden znak typu char %s reťazec ukončený znakom '\0' (netlačí sa) %% tlač znaku % smerníky: %p adresa argumentu - smerník %n argument musí byť typu smerník na int; na adresu, na ktorú ukazuje, ukladá počet doteraz vytlačených znakov - Nepovinné:
príznak (môže sa ich kombinovať i niekoľko, nezáleží na poradí): - výsledok konverzie bude zarovnaný doľava (inak doprava) + výsledok konverzie typu signed bude mať znamienko (inak iba znamienko - pre záporné čísla) ' ' výsledok konverzie bude zľava doplnený znakmi ' ', ak nemá znamienko # má vplyv podľa typu konverzie : d i u c s žiadny o pred číslo pridá znak '0' x X pred číslo pridá znak '0x', resp. '0X' f e E výsledok vždy obsahuje desatinnú bodku g G ako e, E (koncové nuly sa neodstraňujú)
šírka: Dekadické číslo, ktoré udáva minimálny počet znakov na výstupe. Ak je počet platných číslic argumentu väčší ako udaná šírka, neberie sa na ňu ohľad. Minimálny počet tlačených znakov môže byť určený aj nepriamo pomocou znaku '*', ktorý spôsobí, že sa šírka nastaví podľa nasledujúceho (predchádzajúceho) argumentu v zozname argumentov. Ak pred šírkou je uvedená nula, doplní sa výstup zľava nulami. presnosť: Dekadické číslo, ktoré pre konverzie d, i, o, u, x a X znamená minimálny počet číslic na výstupe, pre konverzie e, E a f počet číslic za desatinnou bodkou, pre konverzie g a G maximálny počet významných číslic, pre konverziu s maximálny počet znakov (orezanie reťazca). Samotný znak '.' má význam nuly. Namiesto dekadického čísla môže byť rovnako ako v prípade šírky použitý znak '*'. modifikátor: Je to písmeno, ktoré mení konverziu takto: h konverzia d, i - číslo sa prevedie na typ short int konverzia o, u, x, X - číslo sa prevedie na typ unsigned short int konverzia n - prevedie sa na smerník na short int l konverzia d, i - číslo sa prevedie na typ long int konverzia o, u, x, X - číslo sa prevedie na typ unsigned long int konverzia n - prevedie sa na smerník na long int L konverzia e, E, f, g, G - číslo sa prevedie na typ long double
Vstup a výstup reťazca pomocou všetkých troch úrovní práce ilustruje nasledujúci príklad:
/* priklad pr6_1.c vstup - vystup retazca */
#include <stdio.h>
void main(void)
{
charf s2[30],s3[30],*s1=s3;
int i=0;
printf("Vstup retazca 1.po znakoch:");
while ((s2[i] = getchar()) != '\n') i++;
s2[i++] = '\n';
s2[i] = '\0';
for (i = 0 ; s2[i] != '\0' ; i++) putchar(s2[i]);
printf("Vstup retazca 2.po znakoch:");
while ((*s1++ = getchar()) != '\n');
*s1++ = '\n';
*s1 = '\0';
for (i = 0 ; s3[i] != '\0' ; i++) putchar(s3[i]);
printf("Vstup retazca 1.gets:");
gets(s2);
puts(s2);
printf("Vstup retazca 2.gets:");
s1 = s3;
gets(s1);
puts(s1);
printf("Vstup retazca 1.scanf:");
scanf("%s", s2);
printf("Printf s2 = %s\n", s2);
printf("Vstup retazca 2.scanf:");
scanf("%s", s1);
printf("Printf s1 = %s\n", s1);
}
6.2 Vstup z pamäte a výstup do pamäte
V niektorých prípadoch sa používa formátovaný vstup - výstup v spojitosti nie s vonkajšími zariadeniami (stdin, stdout), ale s reťazcom. Tento vstup - výstup teda umožňuje vykonávať prevod medzi vnútorným tvarom a znakovou reprezentáciou (ASCII) tohoto tvaru. K dispozícii sú pre tento účel dve štandardné funkcie sprintf a sscanf, ktoré sa od vyššie popísaných funkcií printf a scanf líšia iba ďalším argumentom str, ktorý označuje príslušný reťazec (použitý vo funkcii vstupu - výstupu). Ich tvar je :
int sprintf(char *str,const char *format,arg1,...,argn); int sscanf(char *str,const char *format,&arg1,...,&argn);
pričom str je smerník na príslušný vstupný (výstupný) reťazec, ostatné parametre viď vyššie. Prácu s týmito funkciami ilustruje príklad prevodu čísel do reťazca a späť :
/* priklad pr6_2.c vstup - vystup do retazca */
#include <stdio.h>
void main(void)
{
char s2[30],s3[30];
int i=0;
float r;
i=3;
sprintf(s2,"Hodnota i = %d",i);
/* obsahom reťazca s2 bude: Hodnota i = 3 */
printf("Retazec s2 = %s\n",s2);
/* obsahom reťazca s3 bude: 33 3.14 */
strcpy(s3,"33 3.14");
printf("Retazec s3 = %s\n",s3);
sscanf(s3,"%d %f",&i,&r);
/* obsahom premenných bude i:33, r:3.14 */
printf("Hodnota i = %d r = %f\n",i,r);
}