[ Pobierz całość w formacie PDF ]

wczytywany jest znak '\n'.
Plik otwarty w trybie binarnym nie posiada tej cechy, wszystkie znaki są do nie-
go zapisywane i odczytywane z niego dosłownie.
Omawiając funkcję scanf, czytającą ze standardowego wejścia, wspomniałem, że
system operacyjny pozwala zwykle skierować do programu czytającego ze stan-
dardowego wejścia dane z pliku. W takim przypadku plik, z którego będzie czytać
funkcja scanf, będzie się zachowywał jak plik otwarty w trybie tekstowym
(a więc będzie wykonywana konwersja pary znaków '\r' '\n' na znak
'\n').
Istnieje jeszcze jedna, ważniejsza, różnica między plikiem otwartym w trybie
tekstowym a plikiem otwartym w trybie binarnym. W pliku tekstowym znak
o kodzie 0x1a jest traktowany jako znacznik końca pliku. Ponieważ taki znak
zawsze może pojawić się w plikach wykonywalnych, plikach danych i innych
plikach nie zawierających normalnego tekstu, pliki takie zawsze powinny być
otwierane w trybie binarnym.
Wśród standardowych, predefiniowanych plików znajduje się plik stdin odpo-
wiadający standardowemu wejściu. Wywołanie funkcji fscanf z plikiem stdin jako
pierwszym argumentem jest równoważne odpowiedniemu wywołaniu funkcji
scanf.
Dzięki olbrzymim możliwościom formatowanego przekształcania wejścia funk-
cja fscanf umożliwia realizację w prosty sposób nawet skomplikowanego prze-
twarzania zawartości plików. Poniżej przedstawię kilka króciutkich programów,
które są przykładami wykorzystania możliwości funkcji fscanf w przetwarzaniu
plików. Zachęcam Czytelnika by przed przeczytaniem dalszego ciągu spróbował
napisać te programy samodzielnie.
1. Program wypisujący wszystkie co najmniej pięcioliterowe napisy (ciągi
liter i spacji) w dowolnym pliku (także np. pliku .exe).
2. Program wypisujący wiersze pliku wejściowego, które nie są komenta-
rzami. Należy przyjąć, że komentarzem jest wiersz zaczynający się od
znaku średnika poprzedzonego co najwyżej odstępami.
52 Wgłąb języka C
Program wypisujący wszystkie łańcuchy ujęte w znaki cudzysłowu znaj-
dujące się w pliku tekstowym (np. tekście programu).
Wszystkie programy zostały napisane tak, żeby zasadnicza idea przetwarzania
była jak najlepiej widoczna. Programy 2 i 3 są filtrami czytającymi ze standar-
dowego wejścia i piszącymi do standardowego wyjścia. Z tego powodu te dwa
programy używają funkcji scanf a nie fscanf. Używając tych programów nale-
ży podmienić standardowe wejście plikiem:
rem
Rozwiązania zadania 1 nie można przedstawić w postaci filtra, ponieważ pro-
gram ma czytać także pliki binarne (standardowe wejście jest plikiem teksto-
wym).
1. /* plik napisy.c */
#include
char s[100]; /* bufor napisu */
void main(int argc,char *argv[])
{
FILE *in;
if(argc
pliku */
in=fopen(argv[1],"rb"); /* otwórz plik o podanej
nazwie */
while(
EOF !=
fscanf(in,"%*[^abcdefghijklmnopqrstuvwxyz]"
"%[abcdefghijklmnopqrstuvwxyz ]",s)
)
if( strlen( s )>4 ) /* jeżeli napis dłuższy niż 4
znaki */
printf( "%s\n" , s ); /* to wypisz go w osobnej
linii */
}
Pętla while wykonuje się do chwili, gdy funkcja scanf zwróci wartość EOF,
czyli dopóki nie zostanie przeczytany cały plik. Funkcja scanf pomija znaki do
momentu natrafienia na małą literę (aby program wyszukiwał także słowa zawie-
rające duże litery, trzeba je dopisać w nawiasach kwadratowych). Po natrafieniu na
małą literę funkcja scanf wczytuje do tablicy s ciąg liter. Jeżeli wczytany ciąg jest
dłuższy niż 4 znaki, to jest on wypisywany. Cała procedura powtarza się aż do
przeczytania całego pliku. Program ten pokazuje, że przy pomocy funkcji fscanf
można z powodzeniem przetwarzać nawet pliki wykonywalne, które nie są prze-
cież w żaden czytelny sposób sformatowane.
2. /* plik rem.c */
#include
char s[100]; /* bufor
linii */
III Formatowane wejście/wyjście 53
void main()
{
while(EOF != scanf(" ;%*[^\n]") )
/* pomiń linie zaczynajace sie
od ; */
{
scanf("%[^\n]%*c",s); /* wczytaj kolejna
linie */
printf("%s\n",s); /* wypisz wczytana
linie */
}
}
Wywołanie funkcji scanf w warunku pętli while powoduje najpierw pominięcie
początkowych odstępów (spacja na początku ciągu format). Następnie, jeżeli ko-
lejnym znakiem w pliku jest średnik, wykorzystywana jest sekwencja %*[^\n].
Powoduje ona pominięcie wszystkich znaków do końca wiersza. Proszę zauważyć,
że w tym momencie kolejnym wczytywanym znakiem będzie '\n'. Z tego
właśnie powodu drugie wywołanie funkcji scanf w tym obiegu pętli nie wczyta
nic do tablicy s i ograniczy się do pominięcia znaku '\n' (specyfikacja %*c [ Pobierz całość w formacie PDF ]

  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • cukierek.xlx.pl