część 4 biblioteka standardowa wejścia - wyjścia znakowe wejście - wyjście Jarosław Gramacki Instytut Informatyki i Elektroniki

Podobne dokumenty
Funkcje zawarte w bibliotece < io.h >

Biblioteka standardowa - operacje wejścia/wyjścia

Funkcje zawarte w bibliotece < io.h >

Wskaźniki do funkcji. Wykład 11. Podstawy programowania ( język C ) Wskaźniki do funkcji (1) Wskaźniki do funkcji (2)

Pliki w C/C++ Przykłady na podstawie materiałów dr T. Jeleniewskiego

ISO/ANSI C dostęp do plików ISO/ANSI C. ISO/ANSI C dostęp do plików. ISO/ANSI C dostęp do plików. ISO/ANSI C dostęp do plików

ISO/ANSI C dostęp do plików ISO/ANSI C. ISO/ANSI C dostęp do plików. ISO/ANSI C dostęp do plików. ISO/ANSI C dostęp do plików

Operacje na plikach. Informatyka. Standardowe strumienie wejścia i wyjścia

Wykład VI. Programowanie. dr inż. Janusz Słupik. Gliwice, Wydział Matematyki Stosowanej Politechniki Śląskiej. c Copyright 2014 Janusz Słupik

۰ Elementem jednostkowym takiego pliku jest bajt. ۰ Format pliku binarnego: [bajty pliku][eof]

Łącza nienazwane(potoki) Łącza nienazwane mogą być używane tylko pomiędzy procesami ze sobą powiązanymi.

Podstawy programowania w języku C++

Programowanie Procedurale. Pliki w języku C++

Wstęp do programowania INP001213Wcl rok akademicki 2017/18 semestr zimowy. Wykład 12. Karol Tarnowski A-1 p.

wer. 7 z drobnymi modyfikacjami Wojciech Myszka :48:

W języku C każdy plik fizyczny jest ciągiem bajtów, z których każdy może być niezależnie odczytany. Borland 01234

Programowanie Proceduralne

Programowanie w językach wysokiego poziomu

Pliki. Informacje ogólne. Obsługa plików w języku C

Plik jest reprezentowany przez strumień znaków (bajtów) o zmiennej długości. Koniec strumienia identyfikowany jest znacznikiem końca pliku EOF.

Programowanie proceduralne INP001210WL rok akademicki 2015/16 semestr letni. Wykład 6. Karol Tarnowski A-1 p.

Pliki. Informacje ogólne. Obsługa plików w języku C

Programowanie proceduralne INP001210WL rok akademicki 2018/19 semestr letni. Wykład 6. Karol Tarnowski A-1 p.

Programowanie w językach

Podstawy programowania w języku C++

Program wykonujący operację na plikach powinien zachować schemat działania zapewniający poprawną pracę:

MATERIAŁY POMOCNICZE PODSTAWY PROGRAMOWANIA Na podstawie: Programowanie w C - Stworzone na Wikibooks, bibliotece wolny podręczników

Obsługa plików. Laboratorium Podstaw Informatyki. Kierunek Elektrotechnika. Laboratorium Podstaw Informatyki Strona 1. Kraków 2013

Języki programowania. Przetwarzanie plików amorficznych Konwencja języka C. Część siódma. Autorzy Tomasz Xięski Roman Simiński

Podstawy programowania w języku C++

Strumienie i pliki. Programowanie Proceduralne 1

Pobieranie argumentów wiersza polecenia

Ćwiczenie 4. Obsługa plików. Laboratorium Podstaw Informatyki. Kierunek Elektrotechnika. Laboratorium Podstaw Informatyki Strona 1.

INFORMATYKA Studia Niestacjonarne Elektrotechnika

Języki i metody programowania I

Operacje na plikach (niskiego poziomu) < IO.H >

Języki i metodyka programowania. Typy, operatory, wyrażenia. Wejście i wyjście.

Formatowane (tekstowe) wejście/wyjście. Binarne wejście/wyjście.

Obsługa plików. Systemy Operacyjne 2 laboratorium. Mateusz Hołenko. 25 września 2011

ISO/ANSI C - funkcje. Funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje

PRZYKŁADY OPERACJI PLIKOWYCH z wykorzystaniem biblioteki <stdio.h>

ISO/ANSI C dostęp do plików ISO/ANSI C. ISO/ANSI C dostęp do plików. ISO/ANSI C dostęp do plików. ISO/ANSI C dostęp do plików

Argumenty wywołania programu, operacje na plikach

PODSTAW PROGRAMOWANIA WYKŁAD 7 ŁAŃCUCHY

Politechnika Białostocka, Wydział Elektryczny, Katedra Elektrotechniki Teoretycznej i Metrologii ul. Wiejska 45D, Białystok

Ghost in the machine

dr inż. Jarosław Forenc

Języki programowania. Karolina Mikulska-Rumińska Pokój 573, tel Konsultacje wtorek 9-10.

Lekcja 10. Uprawnienia. Dołączanie plików przy pomocy funkcji include() Sprawdzanie, czy plik istnieje przy pmocy funkcji file_exists()

Politechnika Białostocka, Wydział Elektryczny, Katedra Elektrotechniki Teoretycznej i Metrologii ul. Wiejska 45D, Białystok

Programowanie Proceduralne

4. Pliki Informacje ogólne o dostępie do plików w PHP Sprawdzanie istnienia pliku file_exists()

1 Przetwarzanie plików

Ćwiczenie 7. Strumień trójelementowy. A g a EOF... EOF... Wprowadzenie do programowania w języku C. Wskaźnik bieżącej pozycji. bieżącej pozycji.

Katedra Elektrotechniki Teoretycznej i Informatyki. wykład 12 - sem.iii. M. Czyżak

7 Przygotował: mgr inż. Maciej Lasota

OPERACJE WEJŚCIA / WYJŚCIA. wysyła sformatowane dane do standardowego strumienia wyjściowego (stdout)

Klasa iostream... 1 Klasy ofstream, ifstream Struktura FILE... 8

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

Język C : szkoła programowania / Stephen Prata. Gliwice, cop Spis treści

część 6 biblioteka standardowa wejścia - wyjścia 1. sformatowane wejście - wyjście 2. rekordowe (binarne) wejście - wyjście

Katedra Elektrotechniki Teoretycznej i Informatyki. wykład 9 - sem.iii. Dr inż. M. Czyżak

Wykład 15. Literatura. Kompilatory. Elementarne różnice. Preprocesor. Słowa kluczowe

Łącza nienazwane(potoki)

Laboratorium Systemów Operacyjnych. Ćwiczenie 4. Operacje na plikach

Podstawy programowania, Poniedziałek , 8-10 Projekt, część 1

DANE TEKSTOWE W JĘZYKU C/C++ - TABLICE ZNAKOWE

Podział programu na moduły

Ćwiczenie nr 6. Poprawne deklaracje takich zmiennych tekstowych mogą wyglądać tak:

Podstawy programowania w języku C++

Co nie powinno być umieszczane w plikach nagłówkowych:

Temat: Dynamiczne przydzielanie i zwalnianie pamięci. Struktura listy operacje wstawiania, wyszukiwania oraz usuwania danych.

Spis treści JĘZYK C - PLIKI BINARNE. Informatyka 2. Instrukcja do pracowni specjalistycznej z przedmiotu. Numer ćwiczenia INF30

5 Przygotował: mgr inż. Maciej Lasota

Katedra Elektrotechniki Teoretycznej i Informatyki. wykład 7- sem.iii. M. Czyżak

Operacje powiązane z systemem:

ŁAŃCUCHY W JĘZYKU C/C++

INSTRUKCJE REPETYCYJNE PĘTLE

Bardzo szybkie podsumowanie: wykład 4

Wykład VII. Programowanie. dr inż. Janusz Słupik. Gliwice, Wydział Matematyki Stosowanej Politechniki Śląskiej. c Copyright 2014 Janusz Słupik

Stałe i zmienne znakowe. Stała znakowa: znak

Część 4 życie programu

2 Przygotował: mgr inż. Maciej Lasota

#include <stdio.h> void main(void) { int x = 10; long y = 20; double s; s = x + y; printf ( %s obliczen %d + %ld = %f, Wynik, x, y, s ); }

Pliki. Operacje na plikach w Pascalu

Spis treści PLIKI BINARNE W JĘZYKU C. Informatyka 2. Instrukcja do pracowni specjalistycznej z przedmiotu. Numer ćwiczenia INF23

OPERACJE NA PLIKACH. Podstawowe pojęcia:

Stałe, znaki, łańcuchy znaków, wejście i wyjście sformatowane

Pliki wykład 2. Dorota Pylak

PROGRAMOWANIE SYSTEMÓW CZASU RZECZYWISTEGO

1 Pierwsze kroki w C++ cz.3 2 Obsługa plików

Język ANSI C. część 11. Jarosław Gramacki Instytut Informatyki i Elektroniki

Języki i metodyka programowania. Wprowadzenie do języka C

EXAMPLES of file operations using the library <stdio.h>

Podstawy programowania. Wykład Pętle. Tablice. Krzysztof Banaś Podstawy programowania 1

Podstawy informatyki. Informatyka stosowana - studia niestacjonarne. Grzegorz Smyk. Wydział Inżynierii Metali i Informatyki Przemysłowej

Systemy Operacyjne - Operacje na plikach

Język C. Szkoła programowania. Wydanie VI

Programowanie w C++ Wykład 8. Katarzyna Grzelak. 15 kwietnia K.Grzelak (Wykład 8) Programowanie w C++ 1 / 33

Transkrypt:

Język ANSI C część 4 biblioteka standardowa wejścia - wyjścia znakowe wejście - wyjście Jarosław Gramacki Instytut Informatyki i Elektroniki pierwszy podział: Typy dyskowego wejścia - wyjścia standardowe we-wy (strumieniowe we-wy): gdyż korzysta ze standardowej biblioteki funkcji we-wy języka C posiada szeroki zakres poleceń wydaje się, że jest dosyć łatwe w użyciu ukrywa przed programistą szczegóły operacji na plikach (np. buforowanie, automatyczna konwersja danych) gdyż korzysta z możliwości wywoływania systemowych funkcji we-wyj z poziomu języka C systemowe we-wy (niskopoziomowe, deskryptorowe we-wy): węższy zakres poleceń bardziej zbliżone do systemu operacyjnego na którym pracujemy programista obsługuje szczegóły operacji plikowych (np. ręczna obsługa bufora, ręczna konwersja danych gdy jest wymagana) efektywniejsza, szybsza obsługa plików gdyż pracujemy "bliżej" systemu operacyjnego dr inż. Jarosław Gramacki, Instytut Informatyki i Elektroniki, UZ (ver. 1.30) 2

Typy dyskowego wejścia - wyjścia drugi podział: znakowe we-wy dane odczytywane / zapisywane są znak po znaku łańcuchowe we-wy dane odczytywane / zapisywane są całymi wierszami sformatowane we-wy dane odczytywane / zapisywane są analogicznie do prf() i scanf() rekordowe (blokowe) we-wy dane odczytywane / zapisywane są całymi blokami (rekordami). Z reguły w formacie binarnym dr inż. Jarosław Gramacki, Instytut Informatyki i Elektroniki, UZ (ver. 1.30) 3 Typy dyskowego wejścia - wyjścia trzeci podział: format tekstowy / binarny często mylone są dwa pojęcia: tryb tekstowy / binarny pracy z plikiem - dotyczy sposobu tłumaczenia znaków końca linii i znaku końca pliku format tekstowy / binarny zapisu danych na pliku - dotyczy sposobu reprezentacji zapisywanych w pliku danych różnica pomiędzy trybem tekstowym, a binarnym polega na innym traktowaniu znaków 1. nowej linii, 2. końca pliku. W trybie tekstowym przejście do nowej linii jest zapisywane w postaci dwóch znaków CR i LF. Przy czytaniu - podobnie, napotkanie CR i LF jest tłumaczone na znak nowej linii. W trybie binarnym taka erpretacja nie zachodzi - kombinacja CR i LF jest traktowana jako dwa znaki. do tematu powrócimy po zapoznaniu się z podstawowymi funkcjami we-wy. Wtedy podane zostaną odpowiednie przykłady ilustrujące "problem" dr inż. Jarosław Gramacki, Instytut Informatyki i Elektroniki, UZ (ver. 1.30) 4

Biblioteka standardowa wejścia - wyjścia najbardziej podstawowe funkcje z podziałem na rodzaj wejścia-wyjścia znakowe we-wy getc() getchar() fgetc() putc() putchar() fputc() ungetc() rekordowe we-wy fread() fwrite() fseek() ftell() rewind() fgetpos() fsetpos() systemowe we-wy (non-ansi, Low Level I/O) open() close() read() write() łańcuchowe we-wy gets() puts() fgets() fputs() formatowane we-wy scanf() fscanf() sscanf() prf() fprf() sprf() operacje na plikach fopen() fclose() fflush() remove() rename() setvbuf() setbuf() obsługa błędów clearerr() feof() ferror() dr inż. Jarosław Gramacki, Instytut Informatyki i Elektroniki, UZ (ver. 1.30) 5 wybrane deklaracje z stdio.h /* Returned by various functions on end of file condition or error. * /#define EOF (-1) /* * The buffer size as used by setbuf such that it is equivalent to * (void) setvbuf(filesetbuffer, cabuffer, _IOFBF, BUFSIZ). */ #define BUFSIZ 512 /* Constants indicating the position relative to which fseek * sets the file position. Enclosed in ifdefs because io.h could also * define them. (Though not anymore since io.h includes this file now.) */ #ifndef SEEK_SET #define SEEK_SET (0) #endif #ifndef SEEK_CUR #define SEEK_CUR (1) #endif #ifndef SEEK_END #define SEEK_END (2) #endif dr inż. Jarosław Gramacki, Instytut Informatyki i Elektroniki, UZ (ver. 1.30) 6

wybrane deklaracje z stdio.h // File Operations FILE* void fopen (const char* szfilename, const char* szmode); fclose (FILE* fileclose); fflush (FILE* fileflush); remove (const char* szfilename); rename (const char* szoldfilename, const char* sznewfilename); setvbuf (FILE* filesetbuffer, char* cabuffer, nmode, size_t sizebuffer); setbuf (FILE* filesetbuffer, char* cabuffer); // Character / String Input and Output Functions fgetc (FILE* fileread); char* fgets (char* cabuffer, nbuffersize, FILE* fileread); fputc ( c, FILE* filewrite); fputs (const char* szoutput, FILE* filewrite); getc (FILE* fileread); getchar (); char* gets (char* cabuffer); // Unsafe: how does gets know how // long the buffer is? putc ( c, FILE* filewrite); putchar ( c); puts (const char* szoutput); ungetc ( c, FILE* filewasread); dr inż. Jarosław Gramacki, Instytut Informatyki i Elektroniki, UZ (ver. 1.30) 7 wybrane deklaracje z stdio.h // Formatted Output bardzo ciekawy mechanizm funkcji o nieokreslonej liczbie parametrów prf (const char* szformat,...); fprf (FILE* fileprto, const char* szformat,...); sprf (char* cabuffer, const char* szformat,...); // Formatted Input scanf (const char* szformat,...); fscanf (FILE* filereadfrom, const char* szformat,...); sscanf (const char* szreadfrom, const char* szformat,...); // Direct Input and Output Functions size_t fread (void* pbuffer, size_t sizeobject, size_t sizeobjcount, FILE* fileread); size_t fwrite (const void* pobjarray, size_t sizeobject, size_t sizeobjcount, FILE* filewrite); dr inż. Jarosław Gramacki, Instytut Informatyki i Elektroniki, UZ (ver. 1.30) 8

wybrane deklaracje z stdio.h // File Positioning Functions fseek (FILE* filesetposition, long lnoffset, norigin); long ftell (FILE* filegetposition); void rewind (FILE* filerewind); typedef long fpos_t; fgetpos (FILE* filegetposition, fpos_t* pfpos); fsetpos (FILE* filesetposition, fpos_t* pfpos); // Error Functions void void clearerr (FILE* fileclearerrors); feof (FILE* fileisatend); ferror (FILE* fileiserror); perror (const char* szerrormessage); dr inż. Jarosław Gramacki, Instytut Informatyki i Elektroniki, UZ (ver. 1.30) 9 przykład: pobieraj znaki z klawiatury i zliczaj je #include <stdio.h> #define RETURN '\n' // \n == return in UNIX // \r == return in DOS main(void) count = 0; puts("please enter some text."); // Count the letters in 'stdin' buffer. while ( getchar()!= RETURN ) count++; prf("you entered %d characters\n", count); return 0; getchar() odpowiada ogólniejszej funkcji getc(stdin) stdin - standardowy wskaźnik (strumień) plikowy skojarzony zawsze z klawiaturą. Udostępniany zawsze automatycznie. Pozostałe standardowe strumienie: stdout, stderr wprowadzane znaki są buforowane (w buforze klawiatury!) do czasu naciśnięcia ENTER. getchar() "obrabia" je dopiero gdy naciśniemy ENTER i wtedy następuje przesłanie zawartości bufora klawiatury do programu w języku C zwróć uwagę na \n oraz \r dr inż. Jarosław Gramacki, Instytut Informatyki i Elektroniki, UZ (ver. 1.30) 10

getchar() zdefiniowana jest w stdio.h jako makro. Jest to pożyteczne. Unika się w ten sposób narzutu spowodowanego realizacją wywołania funkcji dla każdego przetwarzanego znaku makro jest tłumaczone tylko raz (w momencie kompilacji) podobne funkcje getche(), getch()(nie mają one "problemów" z buforem) NIE są funkcjami standardowymi. W systemie DOS były zdefiniowane w conio.h. W systemie Linux są dostępne w bibliotece ncurses lub termios.h getch This is a nonstandard function that gets a character from keyboard, does not echo to screen. getche This is a nonstandard function that gets a character from the keyboard, echoes to screen. dr inż. Jarosław Gramacki, Instytut Informatyki i Elektroniki, UZ (ver. 1.30) 11, buforowanie getchar() jest buforowana - to uwaga z poprzedniego slajdu jak więc sobie radzić z tym "problemem", gdy buforowanie nie jest nam na rękę? 1. korzystać z dostępnych funkcji niestandardowych: <conio.h> biblioteka dostarczane z wieloma kompilatorami pod DOS, Windows <ncurses.h> - biblioteka dostępna w Linux 2. spróbować wyłączyć buforowanie: funkcja setbuff 3. napisać własne rozwiązanie korzystając np. z systemowego we-wy (systemowe we-wy jest tematem oddzielnego wykładu) // niebuforowany odpowiednik getchar() // czyta w wejścia znak po znaku #include <io.h> // patrz wykład z systemowego we-wy my_getchar (void) char c; // c musi być tu typu char! // gdyż read() akceptuje tylko wskaźniki do znaków return (read(0, &c, 1) == 1)? (unsigned char) c : EOF; dr inż. Jarosław Gramacki, Instytut Informatyki i Elektroniki, UZ (ver. 1.30) 12

, buforowanie main(void) char z; prf("do dziela...\n"); while ( (z = getch())!= 'q') //while ( (z = getche())!= 'q') //while ( (z = my_getchar())!= 'q') //while ( (z = getchar())!= 'q') prf("%c \n", z); return 0; dr inż. Jarosław Gramacki, Instytut Informatyki i Elektroniki, UZ (ver. 1.30) 13 znakowe wejście-wyjście; przykład: wyświetl zawartość pliku na ekranie dużymi literami #include <stdio.h> #include <ctype.h> // for toupper() main(void) c; not char! // Character read from the file. FILE *pfile; // Poer to the file. FILE is a // structure defined in <stdio.h> pfile = fopen ( "/etc/hosts","r" ); // Read one character at a time, checking // for the End of File // EOF is defined in <stdio.h> as -1 while ((c = fgetc ( pfile ))!= EOF ) // all brackets NECESSARY!!! prf( "%c", toupper(c) ); // putchar(toupper(c) ); // or like that // putc (toupper(c), stdout ); // or like that fclose( pfile ); return 0; // Close the file. c; dr inż. Jarosław Gramacki, Instytut Informatyki i Elektroniki, UZ (ver. 1.30) 14

getc() i fgetc() są sobie równoważne funkcje zwracają odczytany ze strumienia następny znak i zwracają jego wartość potraktowaną jako unsigned char i przekształconą do. Po napotkaniu końca pliku albo błędu zwracają EOF znak EOF to sygnał generowany przez system operacyjny informujący o końcu pliku. Znak EOF NIE występuje w pliku ( nie ma przecież znaków o ujemnych kodach!) tylko zmienna typu jest w stanie pomieścić wszystkie możliwe znaki (kody 0-255) oraz znacznik końca pliku (-1). Nie sprawdzi się tu zmienna ani char (-127-128) ani unsigned char (0-255) dr inż. Jarosław Gramacki, Instytut Informatyki i Elektroniki, UZ (ver. 1.30) 15 inne tryby otwarcia pliku "r" - tylko do odczytu "w" - tylko do zapisu (jeśli nie istnieje utwórz) "a" - do odczytu, dane będą dodawane na końcu pliku "r+"- do odczytu i zapisu "w+"- do odczytu i zapisu (jeśli nie istnieje utwórz) "a+" - do odczytu i zapisu, dane będą dodawane na końcu pliku Uwaga. W systemach, w których rozróżnia się pliki tekstowe i binarne (np. DOS / Windows), dołączyć należy literę "b" (np. "rb" - otwarcie pliku do odczytu w trybie binarnym) dr inż. Jarosław Gramacki, Instytut Informatyki i Elektroniki, UZ (ver. 1.30) 16

przykład: zlicz ilość znaków (bajtów) w pliku Plik podaj w trakcie wykonania programu #include <stdio.h> main( argc, char *argv[]) count = 0; FILE *pfile; c; pfile = fopen( argv[1], "r" ); argc: ilość argumentów wywołania programu (włącznie ze ścieżką do programu) *argv[]: tablica wskaźników na te argumenty (wskaźniki na napisy) c = fgetc( pfile ); while ( c!= EOF ) count++; c = fgetc( pfile ); prf( "%d\n", count ); fclose( pfile); return 0; przykładowe wywołanie:./countchars /home/jarek/c/plik.c a co gdy:./countchars /home/jarek/c/plik (brak takiego pliku)? a co gdy:./countchars (brak argumentu)? dr inż. Jarosław Gramacki, Instytut Informatyki i Elektroniki, UZ (ver. 1.30) 17 wersja z obsługą błędów #include <stdio.h> #include <stdlib.h> main( argc,char *argv[]) count = 0; FILE * pfile; c; if (argc < 2) prf("usage: countchars <file name>\n"); exit(1); pfile = fopen(argv[1], "r"); if ( pfile == NULL ) prf("file %s doesn t exist\n", argv[1]); exit(1); c = fgetc( pfile ); while ( c!= EOF ) count++; c = fgetc (pfile); prf("%d\n", count); funkcja fopen tworzy strukturę FILE, wypełnia informacjami jej pola i zwraca wskaźnik na tą strukturę. Jeżeli pliku nie uda się otworzyć, to zwraca wskaźnik NULL wyniki nie zgadzają się z poleceniem dir (DOS, Windows). Na przykład program wyświetli liczbę 498 a z polecenia dir odczytujemy 524? dr inż. Jarosław Gramacki, Instytut Informatyki i Elektroniki, UZ (ver. 1.30) 18

problem trybu otwarcia pliku (końca wiersza) infile = fopen(argv[1], "rb"); // in DOS, Windows // with b - binary mode // without b - text mode plik w DOS/Windows: adadadadaa\r\n adadada adadad adadad\r\n // '\r' '\n' CR/LF plik w Linux/Unix: adadadadaa\n adadada adadad adadad\n problem o podłożu historycznym "wewnątrz" programu w C (działającego w WIN lub Unix) pliki przechowywane są zawsze w konwencji Unix w trybie tekstowym (otwarcie pliku w trybie tekstowym) znak nowej linii \n jest tłumaczony na kombinację \r\n przed zapisem na dysk. Podobnie kombinacja \r\n na dysku jest tłumaczona na \n przy odczycie pliku przez program w C w trybie binarnym takie tłumaczenie NIE następuje analogiczny problem występuje przy transmisji plików protokołem FTP. Polecenia protokołu ascii i binary włączają odpowiednio tryb transmisji tekstowy i binarny dr inż. Jarosław Gramacki, Instytut Informatyki i Elektroniki, UZ (ver. 1.30) 19 problem znaku końca pliku. w trybie tekstowym i binarnym inaczej obsługiwany jest znak końca pliku system operacyjny śledzi długość pliku (bo ta informacja jest znana systemowi operacyjnemu) i sygnalizuje wystąpienie końca pliku po dojściu do jego końca. w trybie tekstowym odczytywany jest znak Ctrl-Z (znak o kodzie dziesiętnym 26 lub 1A szesnastkowo). W trybie binarnym śledzona jest całkowita długość pliku, a koniec pliku sygnalizowany wartością całkowitą -1 (FFFFH). Wartość ta jest zdefiniowana w postaci symbolicznej jako EOF (od ang. end of file). Jeżeli więc w pliku występują dane w formacie binarnym lub tekst w innym kodzie niż ASCII, to w trybie tekstowym, przypadkowe wystąpienie bajtu o wartości 1A, zostanie potraktowane jako koniec pliku! dr inż. Jarosław Gramacki, Instytut Informatyki i Elektroniki, UZ (ver. 1.30) 20

jarek@mykonos:~/c/testy$./a.out bindump_dos.c 2f 2f 20 65 61 63 68 20 6c 69 // each li 6e 65 20 69 73 20 74 65 6e 20 ne is ten 41 53 43 49 49 20 63 6f 64 65 ASCII code 73 20 66 6f 6c 6c 6f 77 65 64 s followed 20 62 79 20 74 65 6e 20 63 68 by ten ch 61 72 61 63 74 65 72 73 d a aracters.. 23 69 6e 63 6c 75 64 65 20 3c #include < 73 74 64 69 6f 2e 68 3e 20 20 stdio.h> 20 20 20 20 20 20 20 20 20 20 d a gdyż program 20 20 20 20 20 20 20 20 d a.. bindump.c pisany 23 69 6e 63 6c 75 64 65 20 3c #include < 73 74 64 6c 69 62 2e 68 3e 20 stdlib.h> był w Windows 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 9 9.. 9 2f 2f 20 66 6f 72 20 65 78.// for ex 69 74 28 29 d a 23 64 65 66 it()..#def 69 6e 65 20 4c 45 4e 47 54 48 ine LENGTH 20 31 30 20 20 20 20 20 20 20 10... 6e 20 45 4f 46 d a 20 20 20 n EOF.. 66 63 6c 6f 73 65 28 66 70 74 fclose(fpt 72 29 3b 20 20 20 20 20 20 20 r); 20 20 20 20 20 20 20 20 20 20 20 20 9 9 9 2f 2f 20 63 6c...// cl 6f 73 65 20 66 69 6c 65 d a ose file.. 20 20 20 72 65 74 75 72 6e 28 return( 30 29 3b d a 20 20 20 7d d 0);... a ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff Na końcu program zaczyna czytać znaki EOF (-1, FFFFFFFF) aż zakończy się pętla for(j=0; j<length; j++). Popraw ten błąd samodzielnie. dr inż. Jarosław Gramacki, Instytut Informatyki i Elektroniki, UZ (ver. 1.30) 21 // each line is ten ASCII codes followed by ten characters #include <stdio.h> #include <stdlib.h> #define LENGTH 10 #define TRUE 1 #define FALSE 0 main( argc, char *argv[] ) FILE *pfile; ch; j, not_eof; unsigned char string[length+1]; // for exit() // length of display line // buffer for chars if(argc!= 2) prf("format:./bindump filename"); exit(1); if( (pfile = fopen(argv[1], "rb"))==null ) prf("can't open file %s", argv[1]); exit(1); not_eof = TRUE; do for(j=0; j<length; j++) if( (ch = getc(pfile)) == EOF ) not_eof = FALSE; prf("%3x ", ch); if (ch > 31) string[j] = ch; else string[j] = '.'; string[j] = '\0'; prf(" %s\n", string); while(not_eof == TRUE); fclose(pfile); return(0); // check arguments // binary read // not EOF flag // chars in one line // read character // clear flag on EOF // pr ASCII code // save pring char // use period for // non-pring char // end string // pr string // quit on EOF // close file dr inż. Jarosław Gramacki, Instytut Informatyki i Elektroniki, UZ (ver. 1.30) 22

znakowe we-wy jarek@mykonos:~/c/testy$ ls -la total 352... -rw-r--r-- 1 jarek staff 1494 Nov 9 01:08 bindump_dos.c -rw-r--r-- 1 jarek staff 1454 Nov 9 01:00 bindump_linux.c... dr inż. Jarosław Gramacki, Instytut Informatyki i Elektroniki, UZ (ver. 1.30) 23 przykład: kopia pliku (polecenie cp) #include <stdio.h> main(void) c; FILE *IFile; FILE *OFile; w jakim trybie otworzyć plik do odczytu w systemie WIN aby "było dobrze"? (uruchomienie programu w systemie 1. Linux, 2. Windows) IFile = fopen("/etc/hosts", "r");// Open the file - no error checking done OFile = fopen("/tmp/hosts", "w"); while ((c = fgetc(ifile))!= EOF) fputc(c, OFile); // send a character to the file fclose(ifile); fclose(ofile); return 1; fgetc i getc oraz fputc i putc są sobie równoważne putc(), getc() są w większości systemów implementowane jako makro dr inż. Jarosław Gramacki, Instytut Informatyki i Elektroniki, UZ (ver. 1.30) 24

dodanie obsługi błędów + pliki jako argumenty programu + wyodrębniona funkcja kopiująca copyfile (const char *IFile, const char *OFile)... if (( IFile = fopen(ifile, "r")) == NULL) return(-1); if (( OFile = fopen((ofile, "w")) == NULL) fclose(ifile); return(-2);... return 0; main ( argc, char* argv[]) iresult; if(argc<3) prf( "Use: %s source_file dest_file", argv[0] ); exit(1); iresult = copyfile ( argv[1], argv[2] ); //... error messages here dr inż. Jarosław Gramacki, Instytut Informatyki i Elektroniki, UZ (ver. 1.30) 25 // counts words in a file #include <stdio.h> #include <stdlib.h> przykład: modyfikacja programu zliczającego znaki aby zliczał słowa w pliku // for exit() main( argc, char *argv[] ) FILE *pfile; char ch; white = 1; count = 0; // whitespace flag // word count if( argc!= 2 ) prf("\nusage:./program filename"); exit(1); if( (pfile = fopen(argv[1], "r")) == NULL) prf("\ncan't open file %s.", argv[1]); exit(1); while( (ch = getc(pfile))!= EOF ) switch( ch ) case ' ' : case '\t': case '\n': white++; break; default: if(white) white = 0; count++; // flag set, // count word fclose( pfile ); prf("\nfile %s contains %d words.", argv[1], count); return(0); // if space, tab, or // newline, set flag // non-whitespace, and dr inż. Jarosław Gramacki, Instytut Informatyki i Elektroniki, UZ (ver. 1.30) 26

void main( argc, char *argv[]) char str[25]; char *dot; b; len; FILE *pout, *pin; przykład: dokonaj konwersji pliku z konwencji WIN do konwencji UNIX if (argc >= 3) FILE *pin = fopen(argv[1], "rb"); FILE *pout = fopen(argv[2], "wb"); if (!pin ) prf("file %s does not exist e\n",argv[1]); else prf("processing of a file: %s\n",argv[1]); b = getc( pin ); while ( b!= EOF ) if ( b!= 13 ) putc(b, pout); b = getc( pin ); fclose(pin); fclose(pout); else prf("\ntoo few parameters\ncalling :\n"); prf("dos2unix <source file> <destination file>"); dr inż. Jarosław Gramacki, Instytut Informatyki i Elektroniki, UZ (ver. 1.30) 27 void main( argc, char *argv[]) char str[25]; char *dot; b, len; FILE *pout, *pin; if (argc >= 2) pin = fopen(argv[1], "rb"); // prepare an output file len = strlen( argv[1]) - strlen( dot = strstr(argv[1], ".")); prf("the substring is: %s\n", dot); strncpy(str, argv[1], len); str[len+1] = '\0'; strcat(str, ".txt"); pout = fopen(str, "wb"); przykład: dokonaj konwersji pliku z konwencji Unix do konwencji WIN if (!pin ) prf("file %s does not exist e\n",argv[1]); else prf("processing of a file: %s\n",argv[1]); prf("output file: %s\n",str); b = getc( pin ); while ( b!= EOF ) if (b == '\xa') putc( '\xd', pout ); // lub '\n' '\r' putc( b, pout ); b = getc( pin ); fclose(pin); fclose(pout); else prf("\ntoo few parameters\ncalling :\n"); prf("unix2dos <source file> <destination file>"); dr inż. Jarosław Gramacki, Instytut Informatyki i Elektroniki, UZ (ver. 1.30) 28

przykład: zmień w pliku char1 na char2 (fragment) main ( argc, char* argv[]) //.prog IFile, OFile char1 char2 char char1, char2; long count = 0;... char1 = *argv[3] // strlen(argv[3]) must not be >1 char2 = *argv[4] // strlen(argv[4]) must not be >1 while ( (c = fgetc(pifile))!= EOF) if ( c == char1 ) count++; c = char2; if ( fputc(c, pofile) == EOF) prf("error in writing to a file %s", argv[2]); return (-1);... fclose( pifile); fclose( pofile);... prf("in file %s, %ld characters %c found\n", argv[1], count, char1); return 0; Jako ćwiczenie: zmodyfikuj program aby można było nim zmieniać jednorazowo większą ilość fraz w pliku. Przykład wywołania:./program fraza11 fraza12 fraza 21 fraza 22 fraza 31 fraza32 dr inż. Jarosław Gramacki, Instytut Informatyki i Elektroniki, UZ (ver. 1.30) 29 przykład: zlicz częstość występowania znaków na wejściu / w pliku #include <stdio.h> #include <ctype.h> #include <limits.h> // for ispr() unsigned long count[uchar_max+1]; /* freq main: display byte frequency counts */ main(void) c; while ((c = getchar())!= EOF) count[c]++; for (c = 0; c <= UCHAR_MAX; c++) if (count[c]!= 0) prf("%.2x %c %lu\n", c, ispr(c)? c : '-', count[c]); return 0; lub getc (stdin) zwróć uwagę na sposób zapamiętania "licznika" każdego znaku w tablicy count[] Inny sposób uruchomienia: c:\temp>project2.exe < main.c 1. Uruchom program gdy jest EOF 2. zamiast EOF wstaw q i uruchom program dla danych: abcdeq abcqdeq dr inż. Jarosław Gramacki, Instytut Informatyki i Elektroniki, UZ (ver. 1.30) 30

przykład: zlicz częstość występowania znaków na wejściu / w pliku #include <stdio.h> #include <ctype.h> #include <limits.h> // for ispr() unsigned long count[uchar_max+1]; /* freq main: display byte frequency counts */ main(void) Zamień "rb" na "rt" i zaobserwuj różnice c; (w systemie Windows) FILE *fp = fopen("plik", "rb"); while ((c = getc(fp))!= EOF) count[c]++; for (c = 0; c <= UCHAR_MAX; c++) if (count[c]!= 0) prf("%.2x %c %lu\n", c, ispr(c)? c : '-', count[c]); return 0; dr inż. Jarosław Gramacki, Instytut Informatyki i Elektroniki, UZ (ver. 1.30) 31 przykład: zlicz częstość występowania znaków na wejściu / w pliku c:\temp>project1.exe 0a - 5 0d - 5 20 4 27 ' 4 30 0 3 31 1 2 33 3 1 5c \ 2 61 a 6 62 b 6 64 d 1 6e n 1 72 r 1 78 x 2 c:\temp>project1.exe 0a - 5 20 4 27 ' 4 30 0 3 31 1 2 33 3 1 5c \ 2 61 a 6 62 b 6 64 d 1 6e n 1 72 r 1 78 x 2 FILE *fp = fopen("plik", "rt"); FILE *fp = fopen("plik", "rb"); dr inż. Jarosław Gramacki, Instytut Informatyki i Elektroniki, UZ (ver. 1.30) 32