7 WEJŚCIE I WYJŚCIE
^ OBSŁUGA BŁĘDÓW - PLIK STDERR I FUNKCJA EXIT
Funkcje getchar i putchar można zdefiniować jako makra za pomocą nazw getc /* filecopy: kopiuj zawartość pliku ifp do pliku ofp */ putc, stdin oraz stdout:
#define getchar() ęjetc(stdin)
#define putchar(c) putc((c), stdout)
Przy formatowanym czytaniu z plików i pisaniu do plików możemy korzystać z fun^ cji fscanf i fprintf. Działają one identycznie jak scanf i printf z jednym wyjątkiem ich pierwszym argumentem jest wskaźnik do obsługiwanego pliku; format jest drugim argumentem.
int fscanf(FILE *fp, char *format, ...) int fprintf(FILE *fp, char *format,...)
Wskaźniki plików stdin i stdout są obiektami typu FILE *. Są jednak stałymi, a nie siennymi, przypisywanie im czegokolwiek jest więc niemożliwe.
|i funkcja
Z tym bagażem wiedzy możemy już napisać program cat służący do sklejania zawar- ■ int fclose(FILE *fp^
tości plików. Przyjmiemy jedno założenie, które zresztą przydaje się też w innych siała odwrotnie niż fopen - zrywa połączenie ustalone przez fopen między wskaź-programach: jeżeli w wierszu polecenia wywołującego program podano argumenty, to akiem pliku a nazwą zewnętrzną, zwalniając wskaźnik dla innego pliku. Większość będą one interpretowane jako nazwy plików i obsługiwane w kolejności wystąpienia, Sternów operacyjnych nakłada ograniczenia na liczbę jednocześnie otwartych pli-
Jeżeli argumentów nie podano, to obsługuje się standardowe wejście. #include <stdio.h>
I* cat: sklej zawartość plików, wersja 1 */ main(int argc, char *argv[ ])
{
FILE *fp;
void filecopy(FILE *, FILE *);
if (argc == 1) /* bez argumentów; kopiuj std. wejście */ filecopy(stdin, stdout); else
while (—argc > 0)
if ((fp = fopen(*++argv, ”r”)) == NULL) {
printf(”cat: nie mogę otworzyć %s\n", *argv); return 1;
} else {
filecopy(fp, stdout); fclose(fp);
return 0;
}
F iiSw w jednym programie, dobrym pomysłem jest więc zwalnianie wskaźników pli-ijw, jak w programie cat, gdy nie są już dłużej potrzebne. Istnieje także drugi powód, iby zamykać pliki wyjściowe - funkcja fclose opróżnia bufor, w którym putc gromada dane wyjściowe. Funkcja fclose jest wywoływana automatycznie dla wszytkich szcze otwartych plików, gdy program kończy się normalnie. (Możesz zamknąć stan-iardowe pliki stdin i stdout, jeśli nie są Ci potrzebne. Można je także przełączyć za ;omocą bibliotecznej funkcji freopen.)
Usługa błędów w programie cat nie jest idealna. Kłopot polega na tym, że jeże-'1 jakiegoś powodu jeden z plików nie jest dostępny, to odpowiedni komunikat zo-;tanie dopisany na koniec sklejanego tekstu wyjściowego. Można to ewentualnie żartować wówczas, gdy wyniki są kierowane na ekran, nie można natomiast wtedy, przesyła się je do innego pliku lub potokiem do innego programu.
%śmy mogli sobie lepiej radzić z takimi sytuacjami, mamy drugi strumień danych Ujściowych, o nazwie stderr, przydzielony programowi w ten sam sposób, jak stratnie stdin i stdout. Dane kierowane do pliku stderr zwykle pojawiają się na ek-nawet wtedy, kiedy standardowe wyjście jest skierowane gdzie indziej.
jtrawmy więc program cat tak, by swoje komunikaty o błędach wypisywał do stanowego pliku błędów.
216
217