Języki programowania
Operacje wejścia/wyjścia
…
z
Operacje wejścia/wyjścia służą do porozumiewania się
programu ze światem zewnętrznym, czyli:
–
użytkownikiem (ekran, klawiatura),
–
pamięcią zewnętrzną.
z
Operacje te nie są częścią języka C/C++, umożliwiają je
standardowo dołączane biblioteki:
–
stdio.h
–
iostream.h
–
…
z
Program komunikuje się z urządzeniem pośrednio,
poprzez tzw. kanał (strumień, źródło).
z
Rzeczywistym urządzeniem jest plik.
Logicznym interfejsem pliku jest strumień.
Strumienie
z
Strumień jest wiązany z plikiem za pomocą operacji
otwarcia, a odłączany za pomocą operacji zamknięcia.
z
Typy strumieni:
–
tekstowe – zawierają kody ASCII (dodatkowe transformacje),
–
binarne.
z
Pracując na danym strumieniu zdefiniowano bieżące
położenie, określające miejsce w pliku, w którym
rozpocznie się następna operacja dostępu.
Standardowe kanały w języku C
z
stdin
standardowe wejście (klawiatura),
z
stdout
standardowe wyjście (monitor),
z
stderr
standardowy kanał błędu (monitor),
z
stdprn
standardowa drukarka (port równoległy),
z
stdaux
standardowe urządzenie pomocnicze (port
szeregowy).
z
Wszystkie kanały, z wyjątkiem stderr można związać z
innymi kanałami, np. ze zbiorem dyskowym.
Wczytywanie znaków i napisów
z
Standard ANSI języka C – znakowe operacje I/O (stdio.h):
–
int getchar(void);
–
int putchar(int);
z
Operacja getchar jest zazwyczaj buforowana.
z
Konwersja:
–
getchar:
unsigned char
-> int -> (char)
–
putchar:
int
-> unsigned char
–
W przypadku błędu obie funkcje zwracają EOF = -1.
z
Zawsze jest lepiej użyć powyższych funkcji zamiast
printf
i scanf dla formatu %c – będzie działać szybciej
i niezawodniej.
Buforowanie
#include <stdio.h>
int main() {
char c;
do {
c = getchar();
putchar('.');
} while(c != '\n');
return 0;
}
z
Co wypisze program?
Wczytywanie znaków i napisów
z
Niestandardowe operacje I/O (conio.h):
–
int getche(void);
(z echem)
–
int getch(void);
(bez echa)
–
int kbhit(void);
(zwraca 0 lub prawda)
z
Wszystkie one od razu zwracają wartość.
z
W wypadku niektórych kompilatorów niestandardowe
funkcje I/O nie są zgodne z funkcjami standardowymi,
takimi jak printf czy scanf – w takim wypadku
równoczesne korzystanie z funkcji obu rodzajów może
spowodować dziwne działanie programu.
z
Czasem można to przezwyciężyć stosując
niestandardowe wersje cprintf i cscanf.
Wczytywanie ciągu znaków
z
Operacje na ciągach znaków (stdio.h):
–
char* gets(char*);
–
int puts(char*);
z
gets
wczytuje do podanego bufora znaki ze stdin aż do
momentu wprowadzenia znaku ’\n’. Następnie, w
buforze. ’\n’ jest zamieniane na NULL.
z
Jeśli czytanie zakończy się powodzeniem, zwracany jest
wskaźnik do bufora, w przeciwnym wypadku – NULL.
z
puts
wyświetla przesłany napis, dołączając na końcu
’\n’
. W wypadku niepowodzenia zwraca EOF.
z
Obie działają szybciej niż printf/scanf.
Funkcja
printf
printf
z
Prototyp:
int printf(char*, ...);
z
Jako pierwszy parametr podajemy napis sterujący,
definiujący format.
z
Ilość i typy następnych parametrów zależą od napisu
sterującego.
z
Funkcja printf nie sprawdza liczby i typów argumentów! –
brak kontroli typów -> błędy!
z
Zwraca liczbę wypisanych znaków.
Definiowanie formatu
z
Napis sterujący może zawierać dwa rodzaje znaków:
–
znaki wyświetlane,
–
specyfikatory formatów – te zaczynają się od znaku
%
.
z
Liczba argumentów musi być równa liczbie
specyfikatorów formatu.
z
Precyzję /minimalną długość/wyrównanie pola dla
wyświetlanych liczb można określić modyfikując kody
formatów:
%
[-][min_dl_pola][.][precyzja]
specyfikator_formatu
Kody formatów
z
%c
z
%s
z
%d, %i
z
%u,
z
%e, %E
z
%f
z
%g, %G
z
%o
z
%x, %X
z
%p
z
%%
z
Znak
z
Ciąg znaków
z
Liczba całkowita ze znakiem (dziesiętnie)
z
Liczba całkowita bez znaku (dziesiętnie)
z
Notacja wykładnicza
z
Liczba zmiennoprzecinkowa z separatorem
z
Krótsza z notacji %f lub %e
z
Liczba całkowita bez znaku (ósemkowo)
z
Liczba całkowita bez znaku (szestnastkowo)
z
Wskaźnik
z
Wypisanie znaku %
Funkcja scanf
z
Prototyp:
int scanf(char*, ...);
z
Specyfikacja formatu jak w przypadku printf.
z
Zwraca liczbę wczytanych zmiennych.; błąd – EOF.
z
Niezmodyfikowane formaty %e, %f, %g wczytują liczby
typu float. Aby wczytać typ double, należy dodać
modyfikator l lub L.
z
Specyfikator formatu
%[]
służy do definiowania zbioru
wprowadzanych znaków.
z
Argumentami mogą być wskaźniki bądź referencje do
zmiennych.
Specyfikator %[]
Specyfikator formatu
%[]
:
z
%[abc]
funkcja może wczytać tylko znaki ‘a’, ‘b’ i ‘c’,
z
%[A-Z]
zakres wczytywanych znaków,
z
%[^024]
wykluczenie wczytywania podanych znaków,
Specyfikator
%*
:
pomijanie danego fragmentu w łańcuchu znaków, np.
dla napisu 123-4567 wczyta n = 123, m = 4567, pominie
‘-’.
int n, m;
scanf("%d
%*c
%d", &n, &m);
Operacje I/O na plikach
z
Typ FILE (stdio.h) – struktura przechowująca
różnorodne informacje o pliku.
z
Otwieranie pliku:
FILE* fopen(char* name, char* mode);
–
mode
określa sposób dostępu do pliku,
–
za pomocą zwróconego wskaźnika dokonywane są wszystkie
operacje na pliku,
–
błąd jest sygnalizowany zwróceniem NULL.
z
Zamykanie pliku:
int fclose(FILE* fp);
–
w przypadku powodzenia zwraca 0, błąd – EOF.
Operacje I/O na plikach tekstowych
z
Wczytywanie i zapisywanie bajtów:
–
int fgetc(FILE*);
–
int fputc(int, FILE*);
z
Wczytywanie i zapisywanie napisów:
–
char* fgets(char*, int, FILE*);
–
int fputs(char*, FILE*);
–
int fscanf(FILE*, char*, ...);
–
int fprintf(FILE*, char*, ...);
z
Wykrywanie błędów:
–
int feof(FILE*);
–
int ferror(FILE*);
Operacje I/O na plikach binarnych
size_t fread(void* buf, size_t s, size_t n, FILE*);
size_t fwrite(void* buf, size_t s, size_t n, FILE*);
z
Funkcje pracują na obiektach o rozmiarze s, w ilości n i
czytają/zapisują je z/do bufora buf.
z
Obie funkcje zwracają liczbę wczytanych/zapisanych
obiektów.
Przykład
int main() {
FILE* fp;
int i;
if((fp = fopen("a.bin","wb"))) {
printf("Error!");
exit(1);
}
i = 100;
if(
fwrite(&i, sizeof(int), 1, fp)
!= 1) {
printf("Error!");
exit(1);
}
fclose(fp);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
Poruszanie się po pliku
z
Odczyt pozycji bieżącej:
long ftell(FILE*);
–
w przypadku błędu zwraca -1.
z
Ustawienie nowej pozycji bieżącej:
int fseek(FILE*, long off, int st);
–
off
określa w bajtach, w jakiej odległości od początku st ma
się znaleźć nowa pozycja;
–
wartości dla st:
z
SEEK_SET
początek pliku,
z
SEEK_CUR aktualna pozycja,
z
SEEK_END
koniec pliku;
–
zwraca 0 w wypadku powodzenia, inną zaś wartość dla błędu.
z
Powrót na początek:
void rewind(FILE*);
Pozostałe operacje
z
int rename(char* old_name, char* new_name);
z
int remove(char* name);
z
int fflush(FILE*);