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