Bardzo szybkie podsumowanie: wykład 5

Transkrypt

Bardzo szybkie podsumowanie: wykład 5
Bardzo szybkie podsumowanie: wykªad 5
wer. 7 z drobnymi mody kacjami!
Wojciech Myszka
2016-05-25 11:55:55 +0200
Uwagi
1. Obowi¡zuje caªy materiaª!
2. Tu tylko podsumowanie.
Formatowane (tekstowe)
wej±cie/wyj±cie. Binarne
wej±cie/wyj±cie.
wer. 7 z drobnymi mody kacjami!
Wojciech Myszka
2016-05-14 16:58:41 +0200
Cz¦±¢ I
Formatowane (tekstowe)
wej±cie/wyj±cie
Otwarcie pliku I
1. Przed skorzystaniem z pliku nale»y go otworzy¢
(open).
2. stdin, stdout, stderr otwarte s¡ w trybie tekstowym.
3. Standardowa biblioteka (stdio.h) zawiera trzy funkcje
fopen, freopen i fclose.
4. Pierwsze dwie sªu»¡ do skojarzenia (powi¡zania)
pliku z odpowiedni¡ struktur¡ danych.
5. Ostatnia powi¡zanie to likwiduje.
6. Wszystkie czynno±ci zwi¡zane z otwieraniem i
zamykaniem plików realizowane s¡ przez System
Operacyjny.
Otwarcie pliku II
Operacj¦ otwarcia pliku (ponownego otwarcia) realizuj¡
funkcje fopen i freopen:
# include < s t d i o . h>
F I L E ∗ fopen ( const char ∗ filename , const char ∗
mode ) ;
F I L E ∗ freopen ( const char ∗ filename , const char ∗
mode,
F I L E ∗ stream ) ;
Otwarcie pliku III
U»ycie:
F I L E ∗ fp ;
...
fp = fopen ( " p l i k . t x t " , "w" ) ;
...
fp = freopen ( " p l i k . t x t " , " r " , fp ) ;
I
Pierwszy parametr ( lename) to wska¹nik do tablicy
tekstowej (na przykªad staªej) zawieraj¡cej naw¦
pliku.
Otwarcie pliku IV
I
Parametr drugi to ci¡g znaków (lub zmienna)
zawieraj¡ca w sposób symboliczny okre±lenie trybu
dost¦pu:
I
I
I
I
I
r otwórz plik tekstowy do odczytu (plik musi istnie¢)
w otwórz plik tekstowy do zapisu (niszcz¡c jego
zawarto±¢ je»eli ju» istnieje)
a (append); otwórz plik tekstowy do dopisywania,
je»eli plik nie istnieje zostanie utworzony.
r+ otwarcie pliku tekstowego do zapisu i odczytu (plik
powinien ju» istnie¢!)
w+ otwórz istniej¡cy plik (kasuj¡c jego zawarto±¢) lub
utwórz nowy plik tekstowy w trybie do zapisu
i odczytu
Otwarcie pliku V
I
a+ otwórz plik tekstowy na ko«cu w trybie do zapisu
i odczytu
Otwarcie pliku VI
Przykªad
# include < s t d i o . h>
...
F I L E ∗pp ;
...
pp = fopen ( " Ala . t x t " , " r " ) ;
i f ( pp == NULL )
{ /∗ B ª ¡d ! ∗/ }
...
f s c a n f ( pp , " %d " , & i ) ;
Otwarcie pliku VII
I
Trzeci parametr (stream tylko w przypadku funkcji
reopen) zawiera wska¹nik do struktury danych
opisuj¡cych strumie« danych.
1. Funkcja fopen() otwiera plik o podanej nazwie we
wskazanym trybie, tworzy struktur¦ danych opisuj¡c¡
go i zwraca do niej adres. W przypadku bª¦du
zwraca NULL.
2. Funkcja freopen() najpierw zamyka otwarty
wcze±niej plik i otwiera go ponownie we wskazanym
trybie, zwracaj¡c wska¹nik do struktury danych
opisuj¡cych strumie«. W przypadku bª¦du zwraca
NULL.
Otwarcie pliku VIII
3. Funkcja fclose() zamyka wskazany plik. W przypadku
bª¦du zwraca NULL.
# include < s t d i o . h>
...
i n t f c l o s e ( F I L E ∗ stream ) ;
stream to wska¹nik do struktury danych opisuj¡cych
strumie« danych.
Przykªad:
...
f c l o s e ( fp ) ;
...
Odczyt formatowany I
1. Funkcje typu scanf
# include < s t d i o . h>
i n t f s c a n f ( F I L E ∗ stream , const char ∗
format , . . . ) ;
i n t s c a n f ( const char ∗ format , . . . ) ;
i n t s s c a n f ( const char ∗ s , const char ∗
format , . . . ) ;
Odczyt formatowany II
Dane czytane s¡ ze wskazanego strumienia (stream) i
interpretowane zgodnie z u»ytym formatem. W
formacie powinna wyst¡pi¢ wystarczaj¡ca liczba
specy kacji aby dostarczy¢ dane dla wszystkich
argumentów.
I
I
I
fscanf zwraca liczb¦ przeczytanych warto±ci lub
warto±¢ EOF
scanf jest odpowiednikiem fscanf, ale dotyczy
strumienia stdin
sscanf jest odpowiednikiem fscanf, z tym, »e dane
czytane s¡ z tablicy znakowej; dotarcie do ko«ca
tabeli jest równowa»ne z dotarciem do ko«ca pliku
Wej±cie: Specy kacja formatu I
Na specy kacj¦ formatu skªadaj¡ si¦:
I odst¦py; Wyst¡pienie w formacie biaªego znaku
(white space) powoduje, »e funkcje z rodziny scanf
b¦d¡ odczytywa¢ i odrzuca¢ znaki, a» do napotkania
pierwszego znaku nie b¦d¡cego biaªym znakiem.
I znaki (ró»ne od % i odst¦pów). Je»eli taki znak
wyst¡pi w specy kacji musi si¦ pojawi¢ w strumieniu
wej±ciowym na odpowiednim miejscu!
I specy kacje konwersji (rozpoczynaj¡ce si¦
znakiem %)
Po znaku % wyst¡pi¢ mo»e:
Wej±cie: Specy kacja formatu II
nieobowi¡zkowy znak ∗ (oznaczaj¡cy, »e
zinterpretowana warto±¢ ma by¢ zignorowana)
I nieobowi¡zkowa specy kacja dªugo±ci pola (okre±la
maksymaln¡ liczb¦ znaków pola)
I jeden z nieobowi¡zkowych znaków h, l (maªa litera
el ) lub L mówi¡cych jak ma by¢ interpretowana
czytana wielko±¢ (h short, l long albo double
w przypadku oat, ll long long, L long double),
I znak okre±laj¡cy typ konwersji.
Po znaku procent (%) wyst¡pi¢ mo»e jeden ze znaków
d liczba caªkowita,
I
Wej±cie: Specy kacja formatu III
i liczba caªkowita (mo»na wprowadza¢ warto±ci
szesnastkowe je»eli poprzedzone znakami
0x lub ósemkowe je»eli poprzedzone 0; 031
czytane z formatem %d to 31 a z formatem %i
to 25),
o liczba caªkowita kodowana ósemkowo,
u liczba caªkowita bez znaku (unsigned int),
x liczba caªkowita kodowana szesnastkowo,
a, e, f, g liczba typu oat; mo»na równie» wczyta¢ w
ten sposób niesko«czono±¢ lub warto±¢ Not a
Number (NaN),
Wej±cie: Specy kacja formatu IV
s ci¡g znaków (na ko«cu zostanie dodany znak
zero),
c znak (lub ci¡g znaków gdy wyspecy kowano
szeroko±¢ pola), nie jest dodawane zero na
ko«cu,
[ odczytuje niepusty ci¡g znaków, z których
ka»dy musi nale»e¢ do okre±lonego zbioru,
argument powinien by¢ wska¹nikiem na char,
n do zmiennej odpowiadaj¡cej tej specy kacji
konwersji wpisana zostanie liczba znaków
przetworzonych przez fscanf,
Wej±cie: Specy kacja formatu V
p w zale»no±ci od implementacji sªu»y do
wprowadzania warto±¢ wska¹ników,
% znak %.
Wej±cie: Specy kacja formatu VI
Format [
Po otwieraj¡cym nawiasie nast¦puje ci¡g
okre±laj¡cy znaki jakie mog¡ wyst¦powa¢ w odczytanym napisie
i ko«czy si¦ on nawiasem zamykaj¡cym tj. ]. Znaki pomi¦dzy
nawiasami (tzw. scanlist) okre±laj¡ mo»liwe znaki, chyba »e
pierwszym znakiem jest ^ wówczas w odczytanym ci¡gu
znaków mog¡ wyst¦powa¢ znaki nie wyst¦puj¡ce w scanlist.
Je»eli sekwencja zaczyna si¦ od [] lub [^] to ten pierwszy
nawias zamykaj¡cy nie jest traktowany jako koniec sekwencji
tylko jak zwykªy znak. Je»eli wewn¡trz sekwencji wyst¦puje
znak − (minus), który nie jest pierwszym lub drugim je»eli
pierwszym jest ^ ani ostatnim znakiem zachowanie jest zale»ne
od implementacji.
Wej±cie: Specy kacja formatu VII
Przykªad
# include < s t d i o . h>
i n t main ( void )
{
int x , y , n;
x = s c a n f ( " %∗d %d %n " , &y , &n ) ;
p r i n t f ( " y= %d , n= %d \ n " , y , n ) ;
p r i n t f ( " x= %d \ n " , x ) ;
return 0 ;
}
Wej±cie: Specy kacja formatu VIII
Dane i wyniki
10 20 30 40
y= 20, n= 6
x= 1
1␣␣␣␣␣2222␣ala␣ma␣kota
y=␣2222,␣n=␣11
x=␣1
Wej±cie: Specy kacja formatu IX
Kolejny przykªad
# include < s t d i o . h>
i n t main ( void )
{
int x , y , z , n;
x = s c a n f ( " %4d %5d %n " , &y , &z , &n ) ;
p r i n t f ( " y= %d , z = %d , n= %d \ n " , y , z , n ) ;
p r i n t f ( " x= %d \ n " , x ) ;
return 0 ;
}
Wej±cie: Specy kacja formatu X
Dane i wyniki
1234567890
y= 1234, z= 56789, n= 9
x= 2
Wej±cie: Specy kacja formatu XI
I jeszcze jeden przykªad
# include < s t d i o . h>
i n t main ( void )
{
int x , y , z , n;
x = s c a n f ( " %4d a %5d %n " , &y , &z , &n ) ;
p r i n t f ( " y= %d , z = %d , n= %d \ n " , y , z , n ) ;
p r i n t f ( " x= %d \ n " , x ) ;
return 0 ;
}
Wej±cie: Specy kacja formatu XII
Dane i wyniki
123b123b
y=␣123,␣z=␣32767,␣n=␣2023244192
x=␣1
1a2␣3␣4␣5␣6␣7␣8␣9
y=␣1,␣z=␣2,␣n=␣4
x=␣2
Wej±cie: Specy kacja formatu XIII
...
# include < s t d i o . h>
i n t main ( void )
{
int x , y , z , n;
x = s c a n f ( " %4da%5d%n " , &y , &z , &n ) ;
p r i n t f ( " y= %d , z = %d , n= %d \ n " , y , z , n ) ;
p r i n t f ( " x= %d \ n " , x ) ;
return 0 ;
}
Wej±cie: Specy kacja formatu XIV
123a123
y= 123, z= 123, n= 7
x= 2
Podchwytliwe pytania I
P: Jak powinna wygl¡da¢ specy kacja wprowadzania
pozwalaj¡ca poprawnie zinterpretowa¢ dane w postaci:
123ala456
O: Oczywi±cie tak: %iala%i lub lepiej %dala%d
P: A jak powinna wygl¡da¢ specy kacja pozwalaj¡ca
przeczyta¢ dane postaci
123ala456
oraz
123ola456
Odpowied¹ b¦dzie dªu»sza. . .
Podchwytliwe pytania II
Popatrzmy na program
# include < s t d i o . h>
i n t main ( void ) {
int x , y , z , n;
char t e k s t [ 1 0 0 ] ;
x = s c a n f ( " %d%3[ a−z ]%d%n " , &y , t e k s t , &z , &n ) ;
p r i n t f ( " y= %d " , y ) ;
p r i n t f ( " t e k s t = %s " , t e k s t ) ;
p r i n t f ( " z = %d " , z ) ;
p r i n t f ( " n= %d \ n " , n ) ;
p r i n t f ( " x= %d \ n " , x ) ;
return 0 ;
}
Podchwytliwe pytania III
123ala20
y= 123 tekst= ala z= 20 n= 8
x= 3
12ooo3456
y= 12 tekst= ooo z= 3456 n= 9
x= 3
123ALA34
y= 123 tekst=
x= 1
z= 1250361488 n= 0
Podchwytliwe pytania IV
Je»eli specy kacj¦ zmienimy na: "%d%∗3[a−z]%d%n" to
dane tekstowe b¦d¡ ignorowane, odpowiednie polecenie
b¦dzie wygl¡da¢ tak:
x = s c a n f ( " %d %∗3[ a−z ]% d%n " , &y , &z , &n ) ;
Podchwytliwe pytania V
Co jeszcze mo»e pojawi¢ si¦ wewn¡trz nawiasów
kwadratowych?
I ci¡g znaków
dotyczy wymienionych znaków: [abc]
I znak ^ na pierwszym miejscu
wszystkie znaki za
wyj¡tkiem wymienionych: [^ABC]
I pocz¡tek−koniec
znaki z podanego zakresu: [a−z]
Warto te» poczyta¢ o wyra»eniach regularnych czasami
nazywanych reguªowymi . . .
Podchwytliwe pytania VI
P: W jaki sposób przeczyta¢ dowolny napis?
I Jak wiadomo specy kacja %s czyta znaki do
pierwszego odst¦pu. Zatem nie mo»na w ten sposób
przeczyta¢ napisau Ala ma kota (ze wzgl¦du na
odst¦py.
I Mo»na wspomóc si¦ wyra»eniami regularnymi:
specy kacja %[aA]s czyta¢ b¦dzie dane tekstowe
zgodne z wzorcem. Czyli tylko litery a lub A.
I U»ycie specy kacji %[^ ]s powoduje przeczytanie
dowolnych znaków a» do znaku odst¦pu (w istocie
znaczy to samo co poprzednio: wzorcem jest dowolny
znak ró»ny od spacji!).
Podchwytliwe pytania VII
I
Co spowoduje zatem specy kacja %[^\n]s?
Rodzina polece« fprintf I
Wszystkie funkcje realizuj¡ formatowane wyprowadzanie
informacji.
# include < s t d a r g . h>
# include < s t d i o . h>
i n t f p r i n t f ( F I L E ∗ stream , const char ∗ format , \
...);
i n t p r i n t f ( const char ∗ format , . . . ) ;
i n t s p r i n t f ( char ∗ s , const char ∗ format , . . . ) ;
i n t v f p r i n t f ( F I L E ∗ stream , const char ∗ format , \
v a _ l i s t arg ) ;
i n t v p r i n t f ( const char ∗ format , v a _ l i s t arg ) ;
i n t v s p r i n t f ( char ∗ s , const char ∗ format , \
v a _ l i s t arg ) ;
Rodzina polece« fprintf II
I
I
I
I
fprintf to podstawowa wersja funkcji
printf u»ywa stdout jako strumienia wyj±ciowego.
sprintf przekazuje sformatowane informacje do
tablicy znakowej (odpowiedniej dªugo±ci)
warianty o nazwie rozpoczynaj¡cej si¦ na v (vfprintf,
fprintf, vsprintf) u»ywaj¡ specy cznej metody
przekazywania listy parametrów zmiennej dªugo±ci
nie b¦dziemy si¦ nimi zajmowa¢.
Wyj±cie: Specy kacje formatu I
Podobnie jak w przypadku formatowanego wprowadzania
danych, zmienna lub staªa tekstowa zawiera informacje o
sposobie wyprowadzania danych. Zasad¡ jest, »e znak %
rozpoczyna specy kacj¦ konwersji, a pozostaªe znaki s¡
wyprowadzane w postaci takiej jak w formacie.
Specjalne wska¹niki mody kuj¡ce sposób konwersji to:
wynik b¦dzie justowany do lewej strony
(standardowo do prawej)
+ Liczby b¦d¡ zapisywane zawsze ze znakiem
odst¦p odst¦p b¦dzie zawsze dodawany przed liczb¡
(chyba, »e liczba poprzedzona jest znakiem)
Wyj±cie: Specy kacje formatu II
# Wynik jest konwertowany do postaci
alternatywnej (zale»nej od typu konwersji)
I dla formatu o powoduje to zwi¦kszenie
precyzji, je»eli jest to konieczne, aby na
pocz¡tku wyniku byªo zero;
I dla formatów x i X niezerowa liczba
poprzedzona jest ci¡giem 0x lub 0X;
I dla formatów a, A, e, E, f, F, g i G wynik
zawsze zawiera kropk¦ nawet je»eli nie
ma za ni¡ »adnych cyfr;
I dla formatów g i G ko«cowe zera nie s¡
usuwane.
Wyj±cie: Specy kacje formatu III
0 Liczby b¦d¡ poprzedzone wiod¡cymi zerami
(dla formatów d, i, o, u, x, X, a, A, e, E, f, F,
g i G)
Szeroko±¢ pola i precyzja I
Minimalna szeroko±¢ pola oznacza ile najmniej znaków ma
zaj¡¢ dane pole. Je»eli warto±¢ po formatowaniu zajmuje
mniej miejsca jest ona wyrównywana spacjami z lewej
strony (chyba, »e podano agi, które mody kuj¡ to
zachowanie). Domy±lna warto±¢ tego pola to 0.
Precyzja dla formatów:
I d, i, o, u, x i X okre±la minimaln¡ liczb¦ cyfr, które
maj¡ by¢ wy±wietlone i ma domy±ln¡ warto±¢ 1;
I a, A, e, E, f i F
liczb¦ cyfr, które maj¡ by¢
wy±wietlone po kropce i ma domy±ln¡ warto±¢ 6;
I g i G okre±la liczb¦ cyfr znacz¡cych i ma domy±ln¡
warto±¢ 1;
Szeroko±¢ pola i precyzja II
dla formatu s maksymaln¡ liczb¦ znaków, które
maj¡ by¢ wypisane.
Szeroko±¢ pola mo»e by¢ albo dodatni¡ liczb¡ zaczynaj¡c¡
si¦ od cyfry ró»nej od zera albo gwiazdk¡. Podobnie
precyzja z t¡ ró»nic¡, »e jest jeszcze poprzedzona kropk¡.
Gwiazdka oznacza, »e brany jest kolejny z argumentów,
który musi by¢ typu int. Warto±¢ ujemna przy okre±leniu
szeroko±ci jest traktowana tak jakby podano ag¦ −
(minus).
I
Rozmiar argumentu I
1. Dla formatów d i i mo»na u»y¢ jednego ze mody kator
rozmiaru:
I
I
I
I
I
hh oznacza, »e format odnosi si¦ do argumentu typu
signed char,
h oznacza, »e format odnosi si¦ do argumentu typu
short,
l (el) oznacza, »e format odnosi si¦ do argumentu
typu long,
ll (el el) oznacza, »e format odnosi si¦ do
argumentu typu long long,
j oznacza, »e format odnosi si¦ do argumentu typu
intmax_t,
Rozmiar argumentu II
I
I
z oznacza, »e »e format odnosi si¦ do argumentu
typu b¦d¡cego odpowiednikiem typu size_t ze
znakiem,
t oznacza, »e »e format odnosi si¦ do argumentu
typu ptrdiff_t.
2. Dla formatów o, u, x i X mo»na u»y¢ takich samych
mody katorów rozmiaru jak dla formatu d i oznaczaj¡
one, »e format odnosi si¦ do argumentu
odpowiedniego typu bez znaku.
Rozmiar argumentu III
3. Dla formatu n mo»na u»y¢ takich samych
mody katorów rozmiaru jak dla formatu d i oznaczaj¡
one, »e format odnosi si¦ do argumentu b¦d¡cego
wska¹nikiem na dany typ.
4. Dla formatów a, A, e, E, f, F, g i G mo»na u»y¢
mody katorów rozmiaru L, który oznacza, »e format
odnosi si¦ do argumentu typu long double.
5. Dodatkowo, mody kator l (el) dla formatu c oznacza,
»e odnosi si¦ on do argumentu typu wint_t, a dla
formatu s, »e odnosi si¦ on do argumenty typu
wska¹nik na wchar_t.
Format I
Funkcje z rodziny printf obsªuguj¡ nast¦puj¡ce formaty:
d, i
argument typu int jest przedstawiany jako
liczba caªkowita ze znakiem w postaci [−]ddd.
o, u, x, X
argument typu unsigned int jest
przedstawiany jako nieujemna liczba
caªkowita zapisana w systemie oktalnym (o),
dziesi¦tnym (u) lub heksadecymalnym (x i X).
f, F
argument typu double jest przedstawiany w
postaci [−]ddd.ddd.
Format II
e, E
argument typu double jest reprezentowany
w postaci [−]d.ddde+dd, gdzie liczba przed
kropk¡ dziesi¦tn¡ jest ró»na od zera, je»eli
liczba jest ró»na od zera, a + oznacza znak
wykªadnika. Format E u»ywa wielkiej litery E
zamiast maªej.
g, G
argument typu double jest reprezentowany
w formacie takim jak f lub e (odpowiednio F
lub E) zale»nie od liczby znacz¡cych cyfr w
liczbie oraz okre±lonej precyzji.
Format III
a, A
argument typu double przedstawiany jest w
formacie [−]0xh.hhhp+d czyli analogicznie jak
dla e i E, tyle »e liczba zapisana jest w
systemie heksadecymalnym.
c
argument typu int jest konwertowany do
unsigned char i wynikowy znak jest
wypisywany. Je»eli podano mody kator
rozmiaru l argument typu wint_t
konwertowany jest do wielobajtowej
sekwencji i wypisywany.
Format IV
s
argument powinien by¢ typu wska¹nik na
char (lub wchar_t). Wszystkie znaki z podanej
tablicy, a» do i z wyª¡czeniem znaku null s¡
wypisywane.
p
argument powinien by¢ typu wska¹nik na
void. Jest to konwertowany na seri¦
drukowalnych znaków w sposób zale»ny od
implementacji.
n
argument powinien by¢ wska¹nikiem na
liczb¦ caªkowit¡ ze znakiem, do którego
zapisana jest liczba zapisanych znaków.
Cz¦±¢ II
Binarne wej±cie/wyj±cie
Otwarcie pliku I
# include < s t d i o . h>
F I L E ∗ fopen ( const char ∗ filename ,
const char ∗mode ) ;
F I L E ∗ freopen ( const char ∗ filename ,
const char ∗mode, F I L E ∗ stream ) ;
...
F I L E ∗ fp ;
I
Pierwszy parametr ( lename) to wska¹nik do tablicy
tekstowej (na przykªad staªej) zawieraj¡cej naw¦
pliku.
Otwarcie pliku II
I
Parametr drugi to ci¡g znaków (lub zmienna)
zawieraj¡ca w sposób symboliczny okre±lenie trybu
dost¦pu:
I
I
I
I
I
rb otwórz plik binarny do czytania
wb utwórz plik do zapisu w trybie binarnym, je»eli
plik istnieje, jego zawarto±¢ zostanie skasowana
ab otwórz plik binarny w trybie do dopisywania (je»eli
plik nie istnieje zostanie utworzony).
r+b lub rb+ zapis i odczyt dla plików binarnych (plik
musi istnie¢)
w+b lub wb+ otwórz w trybie binarnym plik istniej¡cy
(kasuj¡c jego zawarto±¢) lub utwórz plik nowy
w trybie do zapisu i odczytu
Otwarcie pliku III
I
I
a+b lub ab+ otwórz plik w trybie binarnym na ko«cu
w trybie do zapisu i odczytu
Trzeci parametr (stream tylko w przypadku funkcji
reopen) zawiera wska¹nik do struktury danych
opisuj¡cych strumie« danych.
Zapis/Odczyt binarny I
1. fread()
# include < s t d i o . h>
s i z e _ t f r e a d ( void ∗ ptr , s i z e _ t s i z e ,
s i z e _ t nmemb, F I L E ∗ stream ) ;
Funkcja realizuj¡ca dost¦p bezpo±redni do pliku,
pozwala odczyta¢ nmemb elementów o wielko±ci size
ka»dy do tablicy wskazywanej przez ptr ze strumienia
stream.
Funkcja zwraca liczb¦ przeczytanych elementów,
która mo»e by¢ mniejsza od nmemb gdy wyst¡pi bª¡d
lub funkcja dojdzie do ko«ca pliku.
Zapis/Odczyt binarny II
2. fwrite()
# include < s t d i o . h>
s i z e _ t f w r i t e ( const void ∗ ptr , s i z e _ t s i z e ,
s i z e _ t nmemb, F I L E ∗ stream ) ;
Funkcja zapisuje binarnie elementy tablicy wskazanej
przez ptr do strumienia stream. size okre±la wielko±¢
jednego obiektu, a nmemb liczb¦ obiektów.
Zapis tablicy I
# include < s t d i o . h>
i n t main ( )
{
F I L E ∗pp ;
double t [ 1 0 ] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9
};
pp = fopen ( " Ala . t x t " , " wb " ) ;
i f ( pp == NULL )
{
p r i n t f ( " Blad ! \ n " ) ;
return 1 ;
Zapis tablicy II
}
f w r i t e ( t , s i z e o f ( double ) , 10 , pp ) ;
f c l o s e ( pp ) ;
return 0 ;
}
Pliki binarne I
Prosty przykªad
/∗
∗ Odczyt jednej l i c z b y w t r y b i e binarnym
∗/
# include < s t d i o . h>
i n t main ( void )
{
F I L E ∗ fp ;
unsigned i n t e ;
fp = fopen ( " foo . t x t " , " rb " ) ;
i f ( fp == NULL )
{
p r i n t f ( " blad1 \ n " ) ;
Pliki binarne II
Prosty przykªad
return 1 ;
}
i f ( f r e a d (&e , s i z e o f ( e ) , 1 , fp ) == 0 )
{
p r i n t f ( " blad2 \ n " ) ;
return 1 ;
}
p r i n t f ( " e = %u \ n " , e ) ;
return 0 ;
}
Pliki binarne III
Prosty przykªad
1. Plik foo.txt nie istnieje
$ ls
b.c Debug
$ Debug/binarne
blad1
Pliki binarne IV
Prosty przykªad
2. Plik foo.txt istnieje, ale jest pusty
$ touch foo.txt
$ ls -l
razem 8
-rw-r--r-- 1 myszka myszka 319 2008-05-05 12:05 b.c
drwxr-xr-x 2 myszka myszka 4096 2008-05-05 12:05 Debug
-rw-r--r-- 1 myszka myszka
0 2008-05-05 12:12 foo.txt
$ Debug/binarne
blad2
Pliki binarne V
Prosty przykªad
3. Plik istnieje, ma dªugo±¢ trzech bajtów:
$ ls -l
razem 12
-rw-r--r-- 1 myszka myszka 319 2008-05-05 12:05 b.c
drwxr-xr-x 2 myszka myszka 4096 2008-05-05 12:05 Debug
-rw-r--r-- 1 myszka myszka
3 2008-05-05 12:15 foo.txt
$ Debug/binarne
blad2
Pliki binarne VI
Prosty przykªad
4. Plik istnieje, ma dªugo±¢ czterech bajtów:
$ cat foo.txt
abc
$ ls -l
razem 12
-rw-r--r-- 1 myszka myszka 319 2008-05-05 12:05 b.c
drwxr-xr-x 2 myszka myszka 4096 2008-05-05 12:05 Debug
-rw-r--r-- 1 myszka myszka
4 2008-05-05 12:18 foo.txt
$ Debug/binarne
e = 174285409
Zapis i odczyt I
# include < s t d i o . h>
i n t main ( void )
{
F I L E ∗ fp ;
unsigned i n t i , k ;
fp = fopen ( " foo . t x t " , " wb " ) ;
i f ( fp == NULL )
{
p r i n t f ( " blad1 \ n " ) ;
return 1 ;
}
f o r ( i = 0 ; i < 10; i ++ )
Zapis i odczyt II
{
f s e e k ( fp , i ∗ s i z e o f ( i ) , SEEK_SET ) ;
f w r i t e (& i , s i z e o f ( i ) , 1 , fp ) ;
}
f c l o s e ( fp ) ;
fp = fopen ( " foo . t x t " , " rb " ) ;
i f ( fp == NULL )
{
p r i n t f ( " blad1 \ n " ) ;
return 1 ;
}
f o r ( i = 0 ; i < 10; i ++ )
Zapis i odczyt III
{
f s e e k ( fp , ( 9 − i ) ∗ s i z e o f ( i ) ,
SEEK_SET ) ;
f r e a d (&k , s i z e o f ( i ) , 1 , fp ) ;
p r i n t f ( " k= %d \ n " , k ) ;
}
f c l o s e ( fp ) ;
return 0 ;
}
Zapis i odczyt (wariant drugi) I
# include < s t d i o . h>
i n t main ( void )
{
F I L E ∗ fp ;
unsigned i n t i , k ;
fp = fopen ( " foo . t x t " , "w+b " ) ;
i f ( fp == NULL )
{
p r i n t f ( " blad1 \ n " ) ;
return 1 ;
}
f o r ( i = 0 ; i < 10; i ++ )
Zapis i odczyt (wariant drugi) II
{
f s e e k ( fp , i ∗ s i z e o f ( i ) , SEEK_SET ) ;
f w r i t e (& i , s i z e o f ( i ) , 1 , fp ) ;
}
f o r ( i = 0 ; i < 10;
{
f s e e k ( fp , ( 9 − i
SEEK_SET ) ;
f r e a d (&k , s i z e o f (
p r i n t f ( " k= %d \ n " ,
}
f c l o s e ( fp ) ;
i ++ )
) ∗ sizeof ( i ) ,
i ) , 1 , fp ) ;
k) ;
Zapis i odczyt (wariant drugi) III
return 0 ;
}
Operacje na ªa«cuchach znaków
wer. 6 z drobnymi mody kacjami!
Wojciech Myszka
2016-05-08 16:12:27 +0200
Ša«cuch znaków
1. Z ªa«cuchów znaków korzystamy powszechnie.
2. Najprostszy przykªad:
p r i n t f ( " Ala ma kota " ) ;
3. Ša«cuchem znaków (ang: string) jest kazdy napis zawarty w
cudzysªowach.
4. Ša«cuch znaków jest tablic¡ typu char, w której na
ostatniej pozycji znajduje si¦ znak null (znak o kodzie
zero).
char ∗ t e k s t = " J a k i s tam t e k s t " ;
p r i n t f ( " %c \ n " , " p r z y k l a d " [ 0 ] ) ;
/∗ wypisze p − z n a k i w n a p i s a c h sa
numerowane od zera ∗/
p r i n t f ( " %c \ n " , t e k s t [ 2 ] ) ; /∗ wypisze k ∗/
Ša«cuch znaków cd I
1. J¦zyk C nie robi jakich± wielkich rozróznie« mi¦dzy
znakami a cyframi:
# include < s t d i o . h>
i n t main ( void )
{
char t e s t [ ] = " t e s t " ;
int i ;
p r i n t f ( "%ld \n " , sizeof ( test ) ) ;
f o r ( i = 0 ; i < s i z e o f ( t e s t ) ; i ++)
p r i n t f ( " %d \ n " , t e s t [ i ] ) ;
return 0 ;
}
2. Efekt dziaªania tego programu
Ša«cuch znaków cd II
5
116
101
115
116
0
Deklaracje
Ponizsze deklaracje s¡ (w zasadzie równowazne)
char ∗ t e k s t = " J a k i s tam t e k s t " ;
/∗ Umieszcza n a p i s w obszarze danych
programu i p r z y p i s u j e adres ∗/
char t e k s t [ ] = " J a k i s tam t e k s t " ;
/∗ Umieszcza n a p i s w t a b l i c y ∗/
char t e k s t [ ] = { ' J ' , ' a ' , ' k ' , ' i ' , ' s ' , \
' ' , ' t ' , ' a ' , 'm' , ' ' , ' t ' , ' e ' , ' k ' , \
' s ' , ' t ' , ' \0 ' } ;
/∗ Tekst to taka t a b l i c a j a k kazda inna ∗/
Jednak w pierwszym przypadku tekst jest odsyªaczem do staªej!
Elementów tablicy nie mozna zmienia¢!
Operacje na ªa«cuchach
Plik nagªówkowy string.h zawiera de nicje staªych i funkcji
zwi¡zanych z operacjami na ªa«cuchach tekstów.
void
void
int
void
void
void
char
char
int
int
char
size_t
char
∗memccpy ( void ∗, const void ∗, i n t , \
size_t );
∗memchr ( const void ∗, i n t , s i z e _ t ) ;
memcmp( const void ∗, const void ∗ ,\
size_t );
∗memcpy( void ∗, const void ∗ ,\
size_t );
∗memmove( void ∗, const void ∗ ,\
size_t );
∗memset ( void ∗, i n t , s i z e _ t ) ;
∗ s t r c a t ( char ∗, const char ∗ ) ;
∗ s t r c h r ( const char ∗, i n t ) ;
strcmp ( const char ∗, const char ∗ ) ;
s t r c o l l ( const char ∗, const char ∗ ) ;
∗ s t r c p y ( char ∗, const char ∗ ) ;
s t r c s p n ( const char ∗, const char ∗ ) ;
∗s t r d u p ( const char ∗ ) ;
char
size_t
char
int
char
char
char
size_t
char
char
char
size_t
∗strerror ( int );
s t r l e n ( const char ∗ ) ;
∗ s t r n c a t ( char ∗, const char ∗ ,\
size_t );
strncmp ( const char ∗, const char ∗ ,\
size_t );
∗s t r n c p y ( char ∗, const char ∗ ,\
size_t );
∗ s t r p b r k ( const char ∗, const char ∗ ) ;
∗ s t r r c h r ( const char ∗, i n t ) ;
s t r s p n ( const char ∗, const char ∗ ) ;
∗ s t r s t r ( const char ∗, const char ∗ ) ;
∗ s t r t o k ( char ∗, const char ∗ ) ;
∗ s t r t o k _ r ( char ∗, const char ∗ ,\
char ∗∗);
s t r x f r m ( char ∗, const char ∗ ,\
size_t );
Porównywanie ci¡gów znaków
1. Porównywanie pojedynczych znaków
kodów ASCII
na podstawie ich
2. Dla ci¡gów znaków "aaa" > "aa" > "a" > ""; "ab" > "aa"; "a" >
"A"
3. Funkcja strcmp sªuzy do porównywania dwu ci¡gów
znaków; ma dwa parametry i zwraca −1 gdy pierwszy ci¡g
znaków jest mniejszy od drugiego, 0 gdy s¡ równe i +1, gdy
pierwszy ci¡g jest wi¦kszy od drugiego.
4. Funkcja strncmp (o trzech parametrach, trzeci parametr
wskazuje ile znaków ma by¢ porównanych) moze by¢ uzyta,
gdy nie chcemy porównywa¢ caªych ci¡gów znaków.
Kopiowanie znaków
1. Do kopiowania sªuzy funkcja strcpy o dwu parametrach;
ci¡g znakach zawarty w drugim parametrze kopiowany jest
do pierwszego parametru. Do obowi¡zku programisty
nalezy zapewnienie aby tablica b¦d¡ca pierwszym
parametrem miaªa wystarczaj¡c¡ ilo±¢ miejsca na
pomieszczenie caªego zapisu!
2. Drugi wariant funkcji strncpy; dodatkowy, trzeci parametr
mówi ile znaków ma by¢ skopiowanych (ale zawsze
trzeba pami¦ta¢ o miejscu na znak null znajduj¡cym si¦ na
ko«cu napisu). Znaki z drugiego parametry kopiowane s¡ do
ko«ca ªa«cucha, chyba ze tekst jest dªuzszy niz liczba
znaków do skopiowania; w tym przypadku programista musi
doda¢ znak NULL r¦cznie na ko«cu skopiowanego tekstu.
Š¡czenie napisów I
1. Do ª¡czenia napisów sªuzy funkcja strcat (nazwa pochodzi
od STRing conCATenate).
2. Podobnie jak w poprzednich przypadkach jest równiez
drugi wariant strncat
3. W wersji standardowej Zawarto±¢ drugiego parametru
funkcji dopisywana jest na ko«cu zawarto±ci pierwszego.
char t e k s t [ 8 0 ] = " " ;
s t r c a t ( tekst , " ala " ) ;
s t r c a t ( t e k s t , " ma " ) ;
s t r c a t ( t e k s t , " kota " ) ;
puts ( t e k s t ) ;
Š¡czenie napisów II
4. Pierwszy parametr funkcji musi mie¢ dostateczn¡ ilo±¢
miejsca na pomieszczenie poª¡czonych ci¡gów znaków!
5. W drugim wariancie wyst¦puje trzeci parametr mówi¡cy ile
znaków ma by¢ doª¡czonych.
Dªugo±¢ ci¡gu znaków
1. Funkcja strlen podaje dªugo±¢ ci¡gu znaków (bez znaku
NULL)
Wyszukiwanie
1. Funkcja strchr (gdzie pierwszym parametrem jest ci¡g
znaków a drugim pojedynczy znak) zwraca numer znaku
zgodnego z poszukiwanym.
2. Funkcja strrchr poszukuje od prawej do lewej.
3. Funkcja strstr (o dwu parametrach) wyszukuje pierwszego
wyst¡pienia ci¡gu znaków b¦d¡cego drugim parametrem w
pierwszym.
4. Funkcja strtok moze sªuzy¢ do podziaªu pierwszego
parametru na ci¡g zetonów; zakªadamy, ze zetony (tokeny)
oddzielone s¡ zadanym znakiem (drugi parametr).
Konwersje
1. atol, strtol
long
2. atoi
zamienia ªa«cuch na liczb¦ caªkowit¡ typu
zamienia ªa«cuch na liczb¦ caªkowit¡ typu int
3. atoll, strtoll zamienia ªa«cuch na liczb¦ caªkowit¡ typu
long long (64 bity); dodatkowo istnieje przestarzaªa
funkcja atoq b¦d¡ca rozszerzeniem GNU,
4. atof, strtod
przeksztaªca ªa«cuch na liczb¦ typu double
Funkcje ato* nie wykrywaj¡ bª¦dów konwersji
Funkcje zde niowane s¡ w pliku stdlib.h
Rózne informacje
Plik nagªówkowy ctype.h zawiera de nicje funkcji (i róznych
staªych) zwi¡zanych z rozpoznawaniem typów informacji
int
int
int
int
int
int
int
int
int
isalnum ( i n t ) ;
isalpha ( int );
i s a s c i i ( int );
isblank ( int );
i s c n t r l ( int );
i s d i g i t ( int );
isgraph ( int );
islower ( int );
is pr int ( int );
int
int
int
int
int
int
int
int
int
ispunct ( int );
isspace ( int );
isupper ( int ) ;
i s x d i g i t ( int );
toascii ( int );
tolower ( i n t ) ;
toupper ( i n t ) ;
_toupper ( i n t ) ;
_tolower ( i n t ) ;
Konwersje I
i n t a t o i ( const char ∗ s t r i n g ) ;
long a t o l ( const char ∗ s ) ;
double a t o f ( const char ∗ s t r i n g ) ;
Parametrem funkcji jest ci¡g znaków zawieraj¡cy napis, który
ma by¢ skonwertowany
Konwersje II
Funkcje z rodziny strto*
long i n t s t r t o l ( const char ∗ s t r , char ∗∗ endptr , i n t base ) ;
unsigned long i n t s t r t o u l ( const char ∗ s t r , char ∗∗ endptr , i n t base ) ;
double s t r t o d ( const char ∗ s t r , char ∗∗ endptr ) ;
Pierwszym parametrem funkcji jest napis podlegaj¡cy
konwersji, drugim jest znak ograniczaj¡cy napis (moze to by¢
znak NULL). Trzecim parametrem w przypadku funkcji
konwersji do postaci caªkowitej jest podstawa zapisu liczb
(zawarta pomi¦dzy 2 a 36). Specjalna warto±¢ 0 pozwala
automatycznie rozpoznawa¢ liczby postaci 0nnnnn (gdzie n to
cyfra od zera do 7) jako ósemkowe a liczby postaci 0xuuuu jako
szesnastkowe (u to cyfry od zera do 9 oraz a f lub A F)
Unicode I
1. Jezeli ograniczy¢ si¦ do kodowania jednobajtowego (255
znaków) nie ma wªa±ciwie zadnych problemów, poza tym,
ze pogram musi by¢ uruchamiany w odpowiednim
±rodowisku. Dost¦pne kodowania znaków to ISO-8859-n (n
od 1 do 9), cp-12xx, i tak dalej, i tak dalej. . .
2. Standardowe funkcje porównywania ci¡gów znaków nie
b¦d¡ dziaªaªy!
3. Uniwersalny system kodowania znaków Unicode zostaª
dopuszczony do uzytku w standardzie C99
4. Z Unicode tez nie jest ªatwo, mamy kilka rodzajów. Zestaw
znaków Unicode obejmuje ponad 900 tys. symboli. Zapisa¢
to mozna na 3 bajtach.
Unicode II
5. Ze wzgl¦dów technicznych przyj¦to 4 bajty jako
podstawowa wielko±¢ znaku (bo ªatwo jedn¡ instrukcj¡)
wybra¢ z pami¦ci.
6. W praktyce to za duzo, st¡d warianty
6.1 UTF-8 od 1 do 6 bajtów (dla znaków ponizej 65536 do 3
bajtów) na znak; wszystkie standardowe znaki ASCII na
jednym bajcie.
6.2 UTF-16 2 lub 4 bajty (UTF-32) na znak.
6.3 UCS-2 2 bajty na znak przez co znaki z numerami powyzej
65 535 nie s¡ uwzgl¦dnione
7. Domy±lne kodowanie dla C to kodowanie zlezne od
systemu; linux: czterobajtowe!.
Unicode III
Co nalezy zrobi¢, by zacz¡¢ korzysta¢ z kodowania UCS-2
I
I
I
powinni±my korzysta¢ z typu wchar_t (ang. wide
character ), jednak je±li chcemy udost¦pnia¢ kod ¹ródªowy
programu do kompilacji na innych platformach, powinni±my
ustawi¢ odpowiednie parametry dla kompilatorów, by
rozmiar byª identyczny niezaleznie od platformy.
korzystamy z odpowiedników funkcji operuj¡cych na typie
char pracuj¡cych na wchar_t (z reguªy skªadnia jest
identyczna z t¡ róznic¡, ze w nazwach funkcji zast¦pujemy
str na wcs np. strcpy wcscpy; strcmp wcscmp)
je±li przyzwyczajeni jeste±my do korzystania z klasy string,
powinni±my zamiast niej korzysta¢ z wstring, która posiada
zblizon¡ skªadni¦, ale pracuje na typie wchar_t.
Polskie literki
UTF-8!
# include < s t d i o . h>
# include < s t r i n g . h>
i n t main ( void )
{
char n a p i s 1 [ 3 0 ] = " Ala ma kota " ;
char n a p i s 2 [ 3 0 ] = " Ala ma kot ¦ " ;
p r i n t f ( " n a p i s 1 : %d \ n " , ( i n t ) s t r l e n ( n a p i s 1 ) ) ;
p r i n t f ( " n a p i s 2 : %d \ n " , ( i n t ) s t r l e n ( n a p i s 2 ) ) ;
return 0 ;
}
Wyniki:
napis1: 11
napis2: 12
Polskie literki
# include < s t d i o . h>
# include < s t r i n g . h>
# include <wchar . h>
i n t main ( void )
{
char n a p i s 1 [ 3 0 ] = " Ala ma kota " ;
char n a p i s 2 [ 3 0 ] = " Ala ma kot ¦ " ;
wchar_t n a p i s 3 [ 1 2 ] = L " Ala ma kot ¦ " ;
p r i n t f ( " n a p i s 1 : %d \ n " , ( i n t ) s t r l e n ( n a p i s 1 ) ) ;
p r i n t f ( " n a p i s 2 : %d \ n " , ( i n t ) s t r l e n ( n a p i s 2 ) ) ;
p r i n t f ( " n a p i s 3 : %d , s i z e o f n a p i s 3 %d \ n " ,
( i n t ) wcslen ( n a p i s 3 ) ,
( int ) sizeof ( napis3 ) ) ;
return 0 ;
}
Wyniki
napis1: 11
napis2: 12
napis3: 11, sizeof napis3 48
Polskie literki
# include < s t d i o . h>
# include < s t r i n g . h>
# include <wchar . h>
i n t main ( void )
{
int i ;
wchar_t m[ 2 ] = L " A " ;
union ccc {
char n [ 8 ] ;
wchar_t N [ 2 ] ;
} c;
c .N [ 0 ] = m[ 0 ] ;
c .N [ 1 ] = m[ 1 ] ;
f o r ( i =0; i <8; i ++)
p r i n t f ( " %d − %x \ n " , i , c . n [ i ] ) ;
return 0 ;
}
0
1
2
3
4
5
6
7
-
41
0
0
0
0
0
0
0
Polskie literki
# include < s t d i o . h>
# include < s t r i n g . h>
# include <wchar . h>
i n t main ( void )
{
int i ;
wchar_t m[ 2 ] = L " • " ;
union ccc {
char n [ 8 ] ;
wchar_t N [ 2 ] ;
} c;
c .N [ 0 ] = m[ 0 ] ;
c .N [ 1 ] = m[ 1 ] ;
f o r ( i =0; i <8; i ++)
p r i n t f ( " %d − %x \ n " , i , c . n [ i ] ) ;
return 0 ;
}
0
1
2
3
4
5
6
7
-
4
1
0
0
0
0
0
0
Locale
1. Locale to zestaw de nicji okre±laj¡cych specy czny dla
róznych j¦zyków (i krajów) sposób prezentacji róznych
informacji.
2. Z jakich± dziwnych powodów problem nie ma zbyt bogatej
literatury .
3. Jezeli kto± chce si¦ zapozna¢ z pewn¡ realizacj¡ uniksow¡
mog¦ poleci¢ bardzo stary tekst System Operacyjny
HP-UX a sprawa polska.
Locale
Unix
Zachowanie systemu po wyborze okre±lonego j¦zyka zmienia si¦. Za
pomoc¡ kilku zmiennych ±rodowiska mozna regulowa¢ zakres w jakim
podporz¡dkowujemy si¦ specy cznym reguªom. I tak:
LANG okre±la uzywany j¦zyk,
LC_CTYPE de niuje charakter (litery, cyfry, znaki przestankowe,
znaki drukowalne) poszczególnych znaków,
LC_COLLATE okre±la sposób sortowania,
LC_MONETARY opisuje zaznaczania jednostek monetarnych (symbol
waluty, gdzie jest on umieszczany. . . ),
LC_NUMERIC sposób zapisu liczb, znak oddzielaj¡cy grypy cyfr, znak
oddzielaj¡cy cz¦±¢ caªkowit¡ od uªamkowej,
LC_TIME posta¢ podawania daty i czasu,
LC_MESSAGES j¦zyk uzywany w wy±wietlanych komunikatach,
LC_ALL wszystkie LC_*.
Locale
Programowanie
1. Sprawa nie jest prosta!
2. Mozna wszystko zrobi¢ na wiele sposobów.
3. Bardzo cz¦sto komunikaty wyprowadzanie przez (rózne)
programy powtarzaj¡ si¦.
4. Powstaje my±l stworzenia bazy danych zawieraj¡cych
rózne komunikaty oraz ich tªumaczenia na rózne j¦zyki.
5. S¡ tez gotowe biblioteki zapewniaj¡ce obsªug¦ takiej bazy
danych (oraz jej tworzenie).
Locale
Przykªad
Wyniki
# include < s t d i o . h>
$ LANG=C ./stringi
# include < s t d l i b . h>
144
# include < s t r i n g . h>
$ LANG=pl_PL.utf8 ./stringi
# include <wchar . h>
-25
# include < l o c a l e . h>
i n t main ( void )
{
/∗
p r i n t f ( " % s \ n " , getenv ( " LANG " ) ) ; ∗/
s e t l o c a l e ( LC_ALL , getenv ( " LANG " ) ) ;
p r i n t f ( " %d \ n " , w c s c o l l ( L " zó ª ¢ " , L " zó ªw" ) ) ;
return 0 ;
}

Podobne dokumenty