Laboratorium 14: Zaawansowane wejście/wyjście
Transkrypt
Laboratorium 14: Zaawansowane wejście/wyjście
Wojciech Myszka Laboratorium 14: Zaawansowane wejście/wyjście 2016-05-29 09:47:14 +0200 1. Zadanie Napisz program czytający z pliku informacje i wyświetlający każdy bajt w kilku formatach. Na przykład tak: plik o poniższej zawartości: #include <math . h> #include <s t d i o . h> int main ( ) { p r i n t f ( "%l f \n " , pow ( 2 . , 3 . ) ) ; return 0 ; } jest drukowany tak: 0000000 0000010 0000020 0000030 # 043 35 m 155 109 n 156 110 d 144 100 0000040 040 32 i 151 105 a 141 97 c 143 99 i 151 105 m 155 109 n 156 110 t 164 116 l 154 108 o 157 111 a 141 97 c 143 99 h 150 104 u 165 117 . 056 46 i 151 105 040 32 040 32 " 040 32 % 0000050 0000060 040 32 ( l 154 108 . 056 46 d 144 100 h 150 104 n 156 110 p 160 112 l u 165 117 h 150 104 e 145 101 > 076 62 ( 050 40 r 162 114 f d 144 100 > 076 62 040 32 \n 012 10 ) 051 41 i 151 105 \ 1 e 145 101 \n 012 10 < 074 60 i 151 105 \n 012 10 n 156 110 n 040 32 # 043 35 s 163 115 n 156 110 { 173 123 t 164 116 " < 074 60 i 151 105 t 164 116 t 164 116 \n 012 10 f 146 102 , 050 40 0000070 0000080 0000090 0000100 040 32 . 056 46 r 162 114 } 175 125 040 32 p 160 112 ) 051 41 e 145 101 \n 012 10 042 34 o 157 111 040 32 t 164 116 \n 012 10 045 37 w 167 119 ) 051 41 u 165 117 154 108 ( 050 40 ; 073 59 r 162 114 146 102 2 062 50 \n 012 10 n 156 110 134 92 . 056 46 156 110 , 054 44 042 34 040 32 054 44 3 063 51 040 32 040 32 0 060 48 040 32 ; 073 59 040 32 \n 012 10 040 32 0000103 Powyższy efek osiągnięto używając systemowego programu od: od −Ad −cb −td1 −w10 a.c Najpierw jest numer bajtu od początku pliku. Później zawartość tekstowa. kolejne trzy linie zawierają zawartość każdego baju wyświetlaną dziesiętnie, szesnastkowo i ósemkowo. 2. Podpowiedzi 1. Można przećwiczyć pytanie o nazwę pliku i otwieranie go w trybie dowolnym (tekstowym lub binarnym) oraz czytanie linia po linii lub bajt po bajcie. Ale czytanie w trybie tekstowym ogranicza możliwości programu! 2. Równie dobre rozwiązanie to takie w którym program czyta ze standardowego wejścia. Żeby móc czytać również pliki binarne — trzeba czytać je bajt po bajcie (znak po znaku) używając albo funkcji getc(stdin) albo funkcji scanf("%c", $znak). 3. Można również zaprogramować rozwiązanie w którym program po uruchomieniu sprawdza jak został wywołany i w zależności od liczby parametrów albo czyta ze standardowego wejścia (tylko nazwa programu) albo dodatkowy parametr traktuje jako nazwę pliku. Przykładowy program wygląda tak: /∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ czytanie . c C o p y r i g h t 2016 w o j c i e c h myszka <myszka@norka> This program i s f r e e s o f t w a r e ; you can r e d i s t r i b u t e i t and/ or modif i t under t h e terms o f t h e GNU General P u b l i c L i c e n s e as p u b l i s h e d b t h e Free S o f t w a r e Foundation ; e i t h e r v e r s i o n 2 o f t h e License , or ( a t your o p t i o n ) any l a t e r v e r s i o n . 2 ∗ ∗ This program i s d i s t r i b u t e d i n t h e hope t h a t i t w i l l be u s e f u l , ∗ b u t WITHOUT ANY WARRANTY; w i t h o u t even t h e i m p l i e d warranty o f ∗ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See t h e ∗ GNU General P u b l i c L i c e n s e f o r more d e t a i l s . ∗ ∗ You s h o u l d have r e c e i v e d a copy o f t h e GNU General P u b l i c L i c e n s e ∗ a l o n g w i t h t h i s program ; i f not , w r i t e t o t h e Free S o f t w a r e ∗ Foundation , Inc . , 51 F r a n k l i n S t r e e t , F i f t h Floor , Boston , ∗ MA 02110 −1301 , USA. ∗ ∗ ∗/ #include <s t d i o . h> int main ( int argc , char ∗∗ argv ) { FILE ∗ p l i k ; i f ( a r g c == 1 ) { p r i n t f ( " Tylko ␣ j e d e n ␣ argument ␣ ( nazwa␣ programu ) " \ " ␣−−␣ czytam ␣ z ␣ s t d i n \n " ) ; plik = stdin ; /∗ Takie p o d s t a w i e n i e moż na z r o b i ć , i zmienna ∗ p l i k b ę d z i e s t r u k t u r ą z e standardowym wej ś ciem . ∗/ } else { p r i n t f ( " Argumentów␣ w i e c e j , ␣ zakladam , ␣ ż e ␣ p i e r w s z y " \ " ␣ t o ␣nazwa␣ p l i k u : ␣%s \n " , argv [ 1 ] ) ; p l i k = f o p e n ( argv [ 1 ] , " r " ) ; i f ( p l i k == NULL ) { p r i n t f ( " Nie ␣mogę ␣ otworzy ć ␣ p l i k u ! \ n " ) ; return 2 ; } } /∗ ∗ W tym m i e j s c u mamy otworzony p l i k ∗/ 3 char n a p i s [ 1 0 0 ] ; int s t a t u s ; while ( ( s t a t u s = f s c a n f ( p l i k , " %99s " , n a p i s ) ) > 0 ) p r i n t f ( " s t a t u s ␣=␣%d␣ : ␣%s \n " , s t a t u s , n a p i s ) ; f c l o s e ( p l i k ) ; // Zamykamy return 0 ; } 4. Inna metoda polega na wczytaniu całego pliku do tablicy, a następnie wykonaniu wszystkich operacji na danych w pamięci. Tablica będzie typu unsigned char, co może dziwić, ale jest to najprostszy typ pozwalający efektywnie przechowywać zawartość pojedynczych bajtów. /∗ ∗ caly . c ∗ ∗ C o p y r i g h t 2016 w o j c i e c h myszka <myszka@norka> ∗ ∗ This program i s f r e e s o f t w a r e ; you can r e d i s t r i b u t e i t and/ or modif ∗ i t under t h e terms o f t h e GNU General P u b l i c L i c e n s e as p u b l i s h e d b ∗ t h e Free S o f t w a r e Foundation ; e i t h e r v e r s i o n 2 o f t h e License , or ∗ ( a t your o p t i o n ) any l a t e r v e r s i o n . ∗ ∗ This program i s d i s t r i b u t e d i n t h e hope t h a t i t w i l l be u s e f u l , ∗ b u t WITHOUT ANY WARRANTY; w i t h o u t even t h e i m p l i e d warranty o f ∗ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See t h e ∗ GNU General P u b l i c L i c e n s e f o r more d e t a i l s . ∗ ∗ You s h o u l d have r e c e i v e d a copy o f t h e GNU General P u b l i c L i c e n s e ∗ a l o n g w i t h t h i s program ; i f not , w r i t e t o t h e Free S o f t w a r e ∗ Foundation , Inc . , 51 F r a n k l i n S t r e e t , F i f t h Floor , Boston , ∗ MA 02110 −1301 , USA. ∗ ∗ ∗/ #include <s t d i o . h> #include < s t d l i b . h> #include <s t r i n g . h> void usage ( char ∗ name ) { p r i n t f ( " Uzycie : ␣\n " \ " ␣␣␣␣␣␣␣␣%s ␣<nazwa␣ p l i k u >\n " \ 4 " ␣␣␣␣␣␣␣␣ koncze ␣ p r a c e ! \ n " , name ) ; } int main ( int argc , char ∗∗ argv ) { int s t a t u s ; int d l u g o s c ; char p o l e c e n i e [ 2 5 6 ] = { " l s ␣−l ␣ " }; FILE ∗ p l i k ; i f ( a r g c == 1 ) { usage ( argv [ 0 ] ) ; return 1 ; } else { p l i k = f o p e n ( argv [ 1 ] , " rb " ) ; i f ( p l i k == NULL ) { p r i n t f ( " Nie ␣moge␣ otworzy ć ␣ p l i k u ! \ n " ) ; return 2 ; } } f s e e k ( p l i k , 0L , SEEK_END) ; // Przesuwamy wska ź n i k na k o n i e c p l dlugosc = f t e l l ( plik ) ; // Odczytujemy d ł ugo ś ć p l i k u p r i n t f ( " p l i k ␣ma␣ d l u g o s c ␣%d␣ bajtow \n " , d l u g o s c ) ; /∗ ∗ Poni ż e j mał y ż a r c i k . Używam f u n k c j i system do uruchomienia ∗ programu l s , k t ó ry wy ś w i e t l a p o z y c j ę z k a t a l o g u z w i ą zan ą ∗ z p l i k i e m . Moż na tam o d c z y t a ć d ł ugo ś ć p l i k u . ∗/ s t r c a t ( p o l e c e n i e , argv [ 1 ] ) ; system ( p o l e c e n i e ) ; /∗ ∗ P r z y d z i e l a m t a b l i c ę o d p o w i e d n i e j d ł ugo ś c i ∗ Typ u n s i g n e d char wybrano , bo t o n a j p r o s t s z y ∗ typ , w k t órym ł atwo przechowywa ć b a j t y . ∗/ 5 unsigned char ∗ b u f o r = m a l l o c ( d l u g o s c ) ; i f ( b u f o r == NULL ) { p r i n t f ( " Nie ␣moge␣ p r z d z i e l i c ␣ p a m i e c i \n " ) ; return 3 ; } rewind ( p l i k ) ; // Przewijam p l i k na pocz ą t e k s t a t u s = f r e a d ( bufor , 1 , d l u g o s c , p l i k ) ; i f ( s t a t u s != d l u g o s c ) { p r i n t f ( " Cos␣ p o s z l o ␣ z l e ! " ) ; f r e e ( bufor ) ; fclose ( plik ); return 4 ; } /∗ ∗ W tym m i e j s c u mamy w t a b l i c y b u f o r wczytany ca ł y p l i k ∗ moż emy o p r z e t w a r z a ć w dowolny s p o s ó b . ∗ Dost ę p do i−t e g o b a j t u p l i k u uzyskujemy p r z e z ∗ bufor [ i ] ∗/ f r e e ( bufor ) ; fclose ( plik ); return 0 ; } 3. Wersja PDF tego dokumentu. . . . . . pod adresem. Wersja: 55 z drobnymi modyfikacjami! data ostatniej modyfikacji 2016-05-29 09:47:14 +0200 6