wyjścia:
printf()
puts()
wejścia:
scanf()
gets()
Strumienie tekstowe są pogrupowane w wiersze tekstu (do 255 znaków w jednym wierszu) i zakończone znakiem / O (znak końca linii) .
Strumienie binarne to ciąg danych reprezentowanych przez zera i jedynki. Tego typu używa się podczas operacji na plikach.
W języku C istnieje pięć standardowych (zdefiniowanych) strumieni wejścia-wyjścia: stdi n, stdout, stderr, stdprn i stdaux:
Stdin - strumień standardowego wejścia. Korzysta z danych tekstowych
wpisanych z klawiatury.
Stdout - strumień standardowego wyjścia. Służy do przesyłania danych
tekstowych na ekran.
Stderr - strumień „standardowego błędu" . Służy do wyświetlania błędów
na ekranie komputera.
Stdprn - strumień drukarki. Służy do wysyłania danych tekstowych do
portu drukarki.
Stdaux - strumień pomocniczy. Służy do przesyłania danych do portu
COM1 .
funkcje, które pobierają dane ze standardowego wejścia (stdin ) dzielą się na:
- pobierające pojedyncze znaki z klawiatury, np . getcha r ( ) ;
- pobierające z klawiatury całe wiersze, np . gets ( ) ;
- pozwalające na manipulację strumieniami wejścia - scanf ( ) ;
Przykład odczytu znaku z klawiatury i wyświetlenia go na ekranie:
#include <stdio.h> int znak : int main( ) { znak = getchar(); printf("Wpisales znak:"); putchar (znak); printf("\n"); return O; }
funkcja getchar() zwraca wartość typu int , a więc tylko odpowiednik znaku w kodzie ASCII. Nasza zmienna - znak - musi być zatem typu int.
Do wyświetlenia na ekranie pobranego wcześniej znaku używa się funkcji wyjścia putchar( )
Pobieranie całych wierszy, prototyp:
char *gets(char *str);
Funkcja jako argument pobiera wskaźnik do odpowiedniego łańcucha
znaków i również zwraca wskaźnik do innego łańcucha (do typu char)
Funkcją pozwalającą na manipulowanie strumieniami wejścia jest
dobrze Ci znana funkcja scanf ( ) . Mówimy, że funkcja manipuluje strumieniami,
ponieważ może interpretować pobrane wartości z klawiatury
oraz przypisywać je odpowiednim typom zmiennych. Służy do tego
tzw. łańcuch formatowania
scanf( "%d",&zmienna );
W skład każdego specyfikatora konwersji wchodzą następujące znaki:
specyfikator %d informujący o type zmiennej
-opcjonalnie liczba, która określa szerokość pola, czyli liczbę
znaków, jaką scanf( ) ma pobrać ze standardowego wejścia;
-opcjonalnie tzw. -modyfikator precyzji (z ang. precision
modificator) , który modyfikuje znaczenie specyfikatora typu
(listę modyfikatorów precyzji przedstawiono w tabeli 4 . 2 ) .
Tabela 4.2. Modyfikatory precyzji
Modyfikator precyzji Znaczenie
h -Znak ten umieszczony przed specyfikatorami typu d, i , o, u lub x informuje funkcję o tym, że argument jest wskaźnikiem do typu s hort
l - Znak ten umieszczony przed specyfikatorami typu d, i, o, u lub x informuje funkcję o tym, że argument jest wskaźnikiem do typu long
L - Znak ten umieszczony przed specyfikatorami typu e, f lub g informuje funkcję o tym, że argument jest wskaźnikiem do typu longdouble
Program, który pobierze z klawiatury, a następnie wyświetli na ekranie liczbę pięciocyfrową (3 pierwsze cyfry powinny być zapisane w jednej zmiennej , natomiast 2 pozostałe w drugiej)
#include<stdio.h> int liczbal,liczba 2; char napis[30]; int main() { printf("\nWpisz 5-cyfrowa liczbe:"); scanf("%3d%2d",&liczbal,&liczba2); printf("\nWpisales liczby%d i %d.\n",liczbal,liczba2); return O; }
Funkcje wyjścia
Funkcja putchar() wysyła pojedyncze znaki (kody ASCI) do standardowego wyjścia (na ekran) .
Prototyp funkcji putchar()
int putchar(int c);
Kolejną funkcją wyjścia jest funkcja puts(). Pozwala ona wyświetlać na ekranie całe wiersze tekstu.
Prototyp funkcji puts ( ):
int puts(char *cp);
Kopiowanie łańcuchów znaków
Funkcja strcpy() kopiuje cały łańcuch znaków (łącznie ze znakiem \0) do innego miejsca w pamięci komputera. Prototyp funkcji strcpy():
char *strcpy(char *przeznaczenie, char *zrodlo);
Program, który przekopiuje dowolny łańcuch znaków do innego łańcucha, pamiętaj o wcześniejszym zadeklarowaniu docelowego łańcucha oraz o przypisaniu mu pamięci.
#include <stdlib.h> #include <stdio.h> #include <string.h> char zrodlo[]="Nasz lancuch zrodlowy"; char docel1[30]; char *docel 2; int main() { printf("\nLancuch zrodlowy: %s", zrodlo); strcpy (docel1,zrodlo); printf("\n pierwszy lancuch docelowy powykonaniu"); printf("operacji kopiowania: %s",docel1); docel2=(char *)malloc(strlen(zrodlo)+l); strcpy (docel2,zrodlo); printf( "\ndrugi lancuch docelowy po "); printf( "przekopiowaniu: %s \n", docel2); return O ; }
Drugą funkcją służącą do kopiowania łańcuchów znaków jest strncpy(). W przeciwieństwie do funkcji strcpy () funkcja strncpy () pozwala na _określenia liczby znaków, które mają być skopiowane do miejsca przeznaczenia.
Prototyp funkcji strncpy()
char *strncpy ( char *przeznaczenie, char *zrodlo, size_t n );
strncpy ( ) kopiuje pierwsze n znaków łańcucha źródłowego do miejsca przeznaczenia.
Łączenie łańcuchów znaków
Funkcjami używanymi do łączenia łańcuchów znaków są strcat() oraz strncat().
Prototyp funkcji strcat ();
char *strcat(char *lancuchl, char *lancuch2) ;
Funkcja strcat() dodaje kopię łańcucha lancuch2 na koniec łańcucha lancuch1.
Funkcja strncat ( ) jest bardzo podobna do strcat ( ) uwzględnia tylko liczbę znaków.
Operacje na plikach
Aby utworzyć plik w języku C, należy zdefiniować wskaźnik do pliku.
W pliku nagłówkowym <stdio.h> jest zdefiniowany specjalny wskaźnik do tego celu - F I LE *.
Deklaracja wskaźnika do pliku wygląda tak:
FILE *wskaznik_do_pliku;
Aby utworzyć nowy plik lub otworzyć już istniejący, używamy funkcji fopen o następującym prototypie:
FILE* fopen(const char* nazwapliku, const char* tryb ) ;
Funkcja fopen ( ) zwraca wskaźnik do pliku lub NULL (jeśli nie można otworzyć pliku).
Następnie za pomocą tego wskaźnika można przesuwać się w obrębie pliku i odpowiednio go edytować lub odczytywać. Nazwa pliku to ścieżka do pliku lub sama nazwa pliku (jeśli plik znajduje
się w tym samym katalogu, co program wywołujący funkcję.
tryb oznacza sposób otwarcia pliku. Trzy najważniejsze tryby to:
„r" - otwarcie pliku do odczytu;
„w" - otwarcie pliku do zapisu;
„a" - otwarcie pliku w trybie dopisywania.
W celu odczytania pliku tekstowego należy użyć jednej z trzech funkcji:
fscanf, fgetc lub fgets
ODCZYTYWANIE pliku tekstowego fscanf, fgetc, fgets, fread
fscanf działa tak jak scanf, tyle że dodajemy dodatkowo, jako pierwszy parametr, wskaźnik do pliku, który chcemy odczytać, np.:
fscanf ( wskaznik_dopliku, "%d", zmienna_int )
Takie wywołanie funkcji spowoduje odczytanie elementu z pliku jako typ int i przypisanie go do zmiennej zmienna_int
Po odczytaniu kolejnych elementów wskaźnik pliku jest odpowiednio przesuwany na miejsce, w którym kończy się dany element.
Najlepiej korzystać z funkcji fscanf, jeśli odczytujemy plik, który zawiera szczególny rodzaj danych - nie tylko tekst, ale np. liczby różnych typów. Można wtedy bezpośrednio zapisać kolejne elementy pliku do odpowiednich zmiennych
Napisz program, który wypisze na ekranie zawartość utworzonego wcześniej pliku tekstowego o nazwie plik. txt. Plik ten zawiera tylko liczby typu int oraz float zapisane jedna podrugiej. Wykorzystaj funkcję fscanf.
#include <stdio.h> int main () { int a;
FILE *plik;
float b;
if((plik = fopen („plik.txt", "r")) !=NULU) { while ( fscanf( plik, "%d %f", &a, &bl) == 2 ) printf ("%d %f" , a , b); } else return -1; fclose (plik); return 0; }
Odczytywanie pliku tekstowego fgetc
Odczytuje pojedyncze znaki, zwraca int.
Program, który wypisze zawartość pliku plik. txt na ekranie. Plik plik. txt zawiera tylko tekst
#include <stdio.h> int main() FILE *plik; char c; if ((plik=fopen(„plik.txt","r"))!=NULL) { while ((c=fgetc(plik) !=EOF) printf("%c", c): } else return - 1; fclose(plik); return O }
Odczytywanie pliku tekstowego fgets
Funkcja fgets służy do odczytywania z pliku tekstowego kolejnych łańcuchów znaków i zapisywania ich w zmiennej (char * 7 ancuch) przekazywanej jako parametr funkcji. Kolejne znaki z pliku zapełniają łańcuch aż do napotkania znaku końca linii lub zapisania liczby znaków przekazanej jako parametr ( int dlugosc) .
#include <stdio.h> int main() { FILE *plik; char lancuch[80]; if ((plik = fopen("plik.txt","r")) !=NULL) { while (fgets(lancuch.sizeof(lancuch).plik) !=NULL) printf("%s", lancuch); else return -1; fclose (plik); return O : }
fread - odczytanie z pliku danych i zapisanie ich w tablicy (także odczyt plików binarnych)
fread(void *ptr, size_t size, size_t nitems, FILE *stream);
fread zwraca liczbe elementow do odczytania, jak skonczy zwraca 0.
ZAPISYWANIE do pliku tekstowego.
fprintf - jak print ale do pliku
fprintf( wskaznik_dopliku , "%d ", zmienna typu _int )
fputc - zapisuje pojedynczy znak przekazany jako int
int fputc ( int znak , FIL E *wskaznik_dopliku)
fputs - zapisanie łańcucha znaków przekazanego jako parametr
fwrite - zapisanie do pliku danych z tablicy, plik binarny
fwrite(void *ptr, size_t size, size_t nitems, FILE *stream);
Przykłady:
fprintf
Napisz program, który utworzy nowy plik tekstowy o nazwie plik. txt, a następnie zapisze do niego w kolejnych liniach liczby od 0 do 10:
#include <stdio.h> int main() { FILE *plik; int i; if ((plik=fopen("plik.txt","w")) !=NULL { for ( i=O; i<=10; i++) if(fprintf(plik, "%d\n",i)<0) return -1; } else return -1; fclose(plik); return O: }
fputc
Napisz program, który otworzy istniejący plik tekstowy i skopiuje jego zawartość do innego, nowo utworzonego pliku. Wykorzystaj funkcje fputc i fgetc. Nazwy pliku źródłowego i docelowego muszą zostać podane z linii poleceń.
#include <stdio.h> int main ( int argc, char* argv[]) { FILE *plik_zrodlowy, *plik_docelowy; int znak; if (argc !=3) { printf("Uruchomienie programu:nazwa_programu plik_zrodlowy plik_docelowy\n"); return -1; } if((plik_zrodlowy=fopen(argv[1],"r"))==NULL return -l; if ((plik_docelowy=fopen(argv[2],"w"))==NULL return -l; while ((znak=fgetc(plik_zrodlowy)) !=EOF fputc(znak, plik_docelowy); fclose(plik_zrodlowy); fclose(plik=docelowy); return 0; }
fputs - to samo zadanie
różnica tylko w pętli while:
#include <stdio.h> int main ( int argc, char* argv[]) { FILE *plik_zrodlowy, *plik_docelowy; int znak; if (argc !=3) { printf("Uruchomienie programu:nazwa_programu plik_zrodlowy plik_docelowy\n"); return -1; } if((plik_zrodlowy=fopen(argv[1],"r"))==NULL return -l; if ((plik_docelowy=fopen(argv[2],"w"))==NULL return -l; while (fgets(lancuch, sizeof(lancuch) plik_zrodlowy) !=NULL) fputs (launch, plik_docelowy ); fclose(plik_zrodlowy); fclose(plik=docelowy); return 0; }
fwrite:
fwrite(void *ptr, size_t size, size_t nitems, FILE *stream);
Napisz funkcję, która dostaje jako argumenty ścieżki
dostępu do dwóch i przepisuje zawartość pierwszego pliku do drugiego pliku
(stara zawartość drugiego pliku ma zostać skasowana).
Ponieważ w tekście nie jest zaznaczone, że przepisywany
plik jest tekstowy, to należy go przepisać
w trybie binarnym:FREAD zwraca liczbę elementów do zapisania (tutaj 100) jak skończy zwraca 0, co wykorzystuje pętla while.
void przepisz(char * sciezka1, char * sciezka2) { FILE * plik1=fopen(sciezka1,"rb"); FILE * plik2=fopen(sciezka2,"wb"); char c[100]; int n=100; while(n==100){ n=fread(c,1,100,plik1)' fwrite(c,1,n,plik2); } fclose(plik1); fclose(plik2); }