7 WEJŚCIE I WYJŚCIE
Najprostszym mechanizmem wejścia jest czytanie po jednym znaku ze standardowe go wejścia, zwykle klawiatury, za pomocą funkcji getchar:
int getchar(void);
Funkcja ta przy każdym wywołaniu podaje następny znak z wejścia lub EOF, gdy napotkała koniec pliku. Stała symboliczna EOF jest zdefiniowana w nagłówku <stdio.h>. Jej wartością jest na ogół —1, ale w testach należy używać EOF, aby uniezależnić się od takiej specyficznej wartości.
W wielu środowiskach klawiaturę można zastąpić plikiem, stosując konwencję przełączania źródła danych za pomocą symbolu <. Jeśli program próg używa funkcji getchar, to wywołujące ten program polecenie
próg cinfile
spowoduje, że próg będzie czytał znaki z pliku infile, a nie z klawiatury. Przełączenie źródła danych następuje tak, że program nie odczuwa zmiany; w szczególności tekst „<infile” nie jest dołączany do listy argv argumentów wywołania programu. Przełączenie źródła danych jest również niewidoczne wówczas, gdy dane wejściowe napływają z innego programu przez potok (ang. pipe)\ w pewnych systemach polecenie
otherprog | próg
uruchamia dwa programy otherprog i próg, łącząc potokiem standardowe wyjście otherprog ze standardowym wejściem próg.
Funkcja
int putchar(int)
służy do wypisywania danych: wywołanie putchar(c) wysyła znak c do standardowego wyjścia, którym domyślnie jest ekran. Funkcja ta zwraca wartość wypisanego znaku lub EOF (jako sygnał wystąpienia błędu). Wyniki można także kierować do pliku używając symbolu >: jeśli program próg korzysta z funkcji putchar, to polecenie
próg >outfile
spowoduje, że próg zamiast do standardowego wyjścia będzie pisać do pliku outfile Jeżeli system udostępnia potoki, to w poleceniu
próg | anotherprog
standardowe wyjście próg zostanie połączone potokiem ze standardowym wejścia programu anotherprog. ' 5
Dane produkowane przez funkcję printf również są kierowane do wyjścia. Wywołania putchar i printf mogą się przeplatać - wyniki pojawią się na wyjściu zgodnie z kolejnością tych wywołać.
W każdym pliku źródłowym programu, który korzysta z funkcji bibliotecznych realizujących operacje wejścia-wyjścia, przed pierwszym odwołaniem do biblioteki musi wystąpić wiersz
#include <stdio.h>
Gdy nazwa nagłówka jest ujęta w nawiasy < i >, wówczas tego nagłówka szuka się w miejscach standardowo wyróżnionych (np. w systemach Unix zwykle jest to skorowidz /usr/include).
Wiele programów czyta zaledwie jeden strumień danych wejściowych i produkuje jeden strumień danych na wyjściu. Dla takich programów mechanizm wejścia-wyjścia z użyciem funkcji getchar, putchar i printf w zupełności wystarczy. A już na pewno wystarczy początkującym programistom, zwłaszcza gdy używają mechanizmu przełączania oraz mechanizmu potoków do łączenia wyjścia jednego programu z wejściem następnego. Jako przykład rozważmy program lower, który przekształca wielkie litery tekstu wejściowego na małe:
#include <stdio.h>
#include <ctype.h>
main() /* lower: zamień wielkie litery na małe */
int c;
while ((c = getcharf)) 1= EOF) putchar(tolower(c)); return 0;
Funkcja tolower jest zdefiniowana w nagłówku <ctype.h>; przekształca ona wielkie •‘tery na małe nie zmieniając innych znaków. Jak wspomnieliśmy wcześniej, takie ..funkcje”, jak getchar i putchar z nagłówka <stdio.h> oraz tolower z nagłówka <etype.h>, często są makrami, co pozwala uniknąć narzutów, jakie wiążą się z wysłaniem funkcji dla każdego znaku. Jak to zostało zrobione, pokażemy w p. 8.5. Niezależnie od tego, jak funkcje z nagłówka <ctype.h> zostały zrealizowane w kon-
205