POLITECHNIKA WARSZAWSKA
Instytut Automatyki i Robotyki
ZASADY PROGRAMOWANIA KOMPUTERÓW
ZAP zima 2013
Język programowania: C/C++
Środowisko programistyczne: Qt
Wykład 6 : Pliki tekstowe
2
Dodatkowe informacje na temat struktur
Definicja struktury może być umieszczona:
" wewnątrz funkcji main(), na samym początku - wtedy jest dostępna
tylko w tej funkcji
" na zewnątrz funkcji main(), zaraz po using namespace std;
wtedy jest dostępna we wszystkich innych funkcjach też.
To samo odnosi się do definicji stałych.
Jeśli w tablicy mamy rekord o polu napisowym, to do tego pola odwołujemy
się tak, jak do każdego napisu, czyli:
a[i][j].nazwisko[0] pierwszy znak nazwiska zapisanego w elemencie a[i][j]
a[i][j].nazwisko[a[i][j].nazwisko.size()-1] - ostatni znak nazwiska
zapisanego w elemencie a[i][j]
Dla uproszczenia zapisu można użyć zmiennej pomocniczej:
string pom = a[i][j].nazwisko;
pom[0] - pierwszy znak nazwiska
pom[pom.size()-1] - ostatni znak nazwiska
3
Pliki tekstowe
Pliki tekstowe składają się ze znaków (widocznych lub niewidocznych) i są
podzielone na wiersze. Dostęp do plików tekstowych jest możliwy za pomocą
zmiennych plikowych, które są logicznymi modelami plików tekstowych.
Stosuje się dwa typy zmiennych plikowych:
" ifstream - dla plików do odczytu
" ofstream - dla plików do zapisu
Aby dostęp do plików był możliwy, należy dołączyć plik nagłówkowy
.
#include
nazwy zmiennych plikowych
...
ifstream plik_we, wejscie1, dane;
ofstream plik_wy, wyniki;
...
UWAGA: zwykle oprócz działań na plikach używamy działań na konsoli poprzez
cin, cout, stąd zalecane jest jawne dołączanie również pliku (który
zresztą jest standardowo dodawany do szkieletu programu w Qt).
4
Działania na plikach tekstowych
Operacje na PLIKACH TEKSTOWYCH wykonywane są z użyciem funkcji działających na
zmiennych plikowych
zmienna plikowa. open (nazwa_pliku) - otwarcie pliku do odczytu lub zapisu
zmienna plikowa. close ( ) - zamknięcie pliku
zmienna plikowa. clear ( ) - reset pliku (przed ponownym otwarciem)
zmienna plikowa. eof ( ) - funkcja typu boolean, która zwraca informację,
czy napotkano koniec pliku
zmienna plikowa. good ( ) - zwraca informację, czy uzyskano dostęp do pliku
zmienna plikowa. is_open ( ) - zwraca informację, czy plik jest otwarty
nazwa_pliku - łańcuch określający nazwę fizycznie istniejącego pliku, np. :
"dane.txt " - plik dane.txt w katalogu bieżącym
W przypadku Qt jest to katalog o bardzo długiej nazwie postaci:
build-nazwa_projektu-Desktop_Qt_5_0_2_MinGW_32bit-Debug
"C:/wyniki.txt "
"C:\\wyniki.txt " plik wyniki.txt w katalogu głównym na dysku C:
muszą być dwa znaki backslash, bo
pojedynczy oznacza znak sterujący
5
Wczytywanie danych z pliku
Schemat wczytywania danych z pliku
1. otwieramy plik_we do odczytu
#include
...
ifstream plik_we;
lub krócej:
plik_we. open (nazwa_pliku);
ifstream plik_we (nazwa_pliku);
plik_we >> ... ; 2. wczytujemy coś z pliku plik_we
...
plik_we. close ();
...
Zasada wczytywania z pliku kolejnych danych aż do napotkania końca pliku:
plik_we >> ...; // próbujemy coś wczytać z pliku
while (! plik_we. eof() ) { // jeśli nie napotkano końca pliku
3. zamykamy plik_we
...
plik_we >> ...; // próbujemy wczytać kolejne dane
Uwaga: plik o podanej
}
nazwie musi istnieć !
6
Zapisywanie danych do pliku
Schemat zapisywania danych do pliku
1. otwieramy plik_wy do zapisu
#include
...
lub krócej:
ofstream plik_wy;
ofstream plik_wy (nazwa_pliku);
plik_wy. open (nazwa_pliku);
plik_wy << ... ;
... 2. zapisujemy coś do pliku plik_wy
plik_wy. close ();
...
Uwaga: Jeśli plik o podanej
nazwie nie istnieje, zostanie
utworzony.
3. zamykamy plik_wy
Jeśli istniał, zostanie zapisany
nową zawartością (ale nie wolno
zapomnieć o zamknięciu pliku!)
7
Dopisywanie do pliku
Schemat dopisywania danych do pliku
#include
ofstream plik_wy (nazwa_pliku, ios::app);
...
krócej
ofstream plik_wy;
1. otwieramy plik_wy do
plik_wy. open (nazwa_pliku, ios::app);
dopisywania
plik_wy << ...;
...
2. dopisujemy coś do pliku plik_wy
plik_wy. close ();
...
Uwaga: Jeśli plik o podanej
nazwie nie istnieje, zostanie
utworzony.
3. zamykamy plik_wy
8
Instrukcje wczytywania z pliku i drukowania do pliku
1. Jeśli wprowadzamy dane z pliku, a nie z klawiatury, to
zamiast cin używamy zmiennej plikowej:
zmienna_plikowa >> zmienna_1 >> zmienna_2 ... >> zmienna_n;
Uwaga: liczby w pliku z danymi podaje się tak, jak dane liczbowe z
klawiatury, czyli muszą być oddzielone spacjami lub Enterami.
plik_we >> zmienna;
getline (plik_we, napis); działanie dla plik_we analogiczne
plik_we.get (znak); jak dla cin (wykład 4)
plik_we.ignore( );
2. Jeśli wyprowadzamy dane do pliku, a nie na monitor, to
zamiast cout używamy zmiennej plikowej:
zmienna_plikowa << wyrażenie_1 << ... wyrażenie_n
plik_wy << fixed << setprecision (d);
plik_wy << setw(12) << x[i][j];
9
Przykłady czytania z pliku c.d.
Wczytywanie z pliku imion i nazwisk oraz drukowanie ich na ekranie:
#include
#include
#include
...
string imie, nazwisko;
ifstream dane ("dane.txt");
...
dane >> imie >> nazwisko; // próbuje wczytać z pliku imie i nazwisko
while (! dane. eof() ) {
cout << setw(12) << imie << setw(20) << nazwisko << endl;
dane >> imie >> nazwisko; // próbuje wczytać kolejne imie i nazwisko
}
UWAGA: jeśli chcemy, by imiona i nazwiska były wczytywane z kolejnych linii
pliku (wraz z pominięciem ewentualnej reszty linii), to zaraz za instrukcją:
dane >> imie >> nazwisko;
należy dodać instrukcję następującą:
getline (dane, reszta_wiersza);
gdzie reszta_wiersza jest typu string.
10
Sprawdzanie nazwy pliku
Uwaga: w przypadku czytania danych z pliku,
plik o podanej nazwie musi istnieć!
Aby sprawdzić, czy dany plik dał się otworzyć, korzysta się z funkcji good():
int main() {
&
do strumienia cerr
dane. open (... );
wysyła się komunikaty o
if ( !dane. good() ) {
błędach (jest to odrębny
cerr << " Blad otwarcia pliku" << endl ;
rodzaj strumienia, obok
return 1; // zakończenie pracy programu
cin i cout); ale można
// po napotkaniu błędu
wysłać też po prostu do
}
cout
// dalej działania na plikach
// i cala reszta programu
return 0; // poprawne zakończenie pracy programu
}
11
Wczytywanie nazwy pliku
nazwa_pliku otwieranego do odczytu lub zapisu może być zmienną, ale zmienna ta
musi być typu tablica znaków, czyli można użyć zmiennej string, ale
przekonwertowanej do tablicy znaków za pomocą funkcji konwersji c_str().
Przykłady:
string nazpl;
cout << "z jakiego pliku dane?\n "
cin >> nazpl; // wczytanie nazwy pliku;
getchar(); // wczytanie z bufora niewidocznego znaku kończącego nazwę
ifstream dane; // definicja zmiennej plikowej
Uwaga: Jeśli jako nazwę pliku
dane. open (nazpl.c_str() ); // otwarcie pliku do odczytu
podamy "con" (konsola), to
// dalej sprawdzenie funkcją good, czy plik dał się otworzyć
wczytywanie będzie się
odbywać z klawiatury
string nazpl;
(analogicznie zapis do pliku o
ifstream dane;
nazwie "con" oznacza
do { // wymuszamy podanie właściwej nazwy pliku
wyświetlenie wyników na
cout << " podaj nazwę istniejącego pliku z danymi " << endl;
ekranie).
cin >> nazpl;
W przypadku wczytywania z
getchar();
klawiatury koniec danych
dane. open (nazpl.c_str() );
(eof...) sygnalizuje się
if (!dane. good() ) { // jeśli błąd otwarcia pliku
wciskając naraz klawisze Ctrl-
dane. close(); // zamknij plik
Z.
dane. clear(); // zresetuj plik
}
} while (!dane.is_open()); // dopóki nie otwarto pliku
12
Przykład 1 Plik jako zbiór znaków
Dany jest plik znaki.txt , zawierający ciąg znaków zakończony znakiem ? . Wydrukować
trzeci od końca znak, będący dużą literą.
ALGORYTM z3 z2 z1
z3 z2 z1 z ( gdy z jest dużą literą )
dane >> z; // wczytaj pierwszy znak z pliku
#include
while (z !='?' {
#include
if (z>='A' && z<='Z') {
using namespace std;
z3=z2;
z2=z1;
int main() {
z1=z;
char z, z1, z2, z3;
}
z3=z2=z1=' ';
dane >> z; // wczytaj kolejny znak z pliku
ifstream dane("znaki.txt");
}
dane.close();
cout << "trzeci od konca: " << z3 ;
return 0;
}
13
Przykład 2 Plik jako zbiór wierszy
Z pliku "dane.txt" przepisać do pliku "wyniki.txt" co najwyżej N ostatnich wierszy (N -
stała). UWAGA: jeśli w pliku będzie mniej niż N wierszy, należy przepisać je wszystkie.
ALGORYTM
getline (dane, wiersz); // wczytaj pierwszy wiersz
#include while (!dane.eof()) {
licz++;
#include
if (licz#include
a[licz] = wiersz;
using namespace std;
else {
const int N=10;
for (i=0; iint main ( ) {
a[i] = a[i+1]; // w pętli for i
int i;
a[N-1] = wiersz; // a to już jest poza pętlą for i
string a[N];
}
string wiersz;
getline (dane, wiersz); // wczytaj kolejny wiersz
ifstream dane ("dane.txt");
}
ofstream wyniki ("wyniki.txt");
for (i=0; i wyniki << a[i]< for (i=0; i // dodając znak przejścia do nowej linii
a[i] = " ";
dane.close (); wyniki.close ();
return 0;
int licz=-1;
}
14
Przykład 3a Plik jako zbiór wartości liczbowych
int main() {
Dany jest plik tekstowy "wsp.txt "
Tpunkt punkty[N]; // tablica rekordów
zawierający współrzędne (x,y) dowolnej
Tpunkt pkt; // rekord pomocniczy
liczby punktów. Wydrukować współrzędne
int lp=0; // licznik początkowy
N-tego od końca punktu (N stała).
int lc=0; // licznik cykliczny
ifstream dane ("wsp.txt");
dane >> pkt.x >> pkt.y; // pierwsze czytanie
while (! dane. eof()) {
if (lpBufor cykliczny
punkty [lp]=pkt;
lp++;
}
else {
ostatnio wpisany
punkty [lc]=pkt;
punkt
lc++;
if (lc>N-1) // gdy bufor się zapełni
N- ty od końca punkt
lc=0; // wracamy na początek
}
dane >> pkt.x >> pkt.y; // czytanie w pętli
#include
}
#include
dane. close();
using namespace std;
if (lp< N)
struct Tpunkt {
cout<<"za malo punktow \n";
double x, y;
else
};
cout << punkty[lc]. x << " " << punkty[lc]. y;
const int N=100;
return 0;
}
15
Przykład 3b Plik jako zbiór wartości liczbowych
Z pliku "h:\dane.txt" wczytać dane całkowite do
Wersja B: Sprawdzić, czy plik istnieje,
tablicy a[N] (N stała) i wydrukować ją.
a jeśli danych w pliku będzie za mało,
uzupełnić tablicę zerami.
Wersja A - najprostsza:
#include
Przyjąć, że plik istnieje i jest w nim
#include
dostatecznie dużo danych
using namespace std;
#include
int main() {
#include
const int N=100;
using namespace std;
int a[N], i, j;
ifstream we ("h:\\dane.txt");
int main() {
if (!we.good()) {
const int N=20;
cout<<"brak dostepu do pliku";
int a[N], i, j;
return 1;
ifstream we ("h:\\dane.txt");
}
for (i=0; ifor (i=0; i we >> a[i];
a[i]=0; // najpierw zerujemy całą tablicę
we.close();
for (i=0; ifor (i=0; i we >> a[i]; // tylko tyle liczb, ile jest w pliku
cout << a[i] << "\t ";
we.close();
return 0;
for (i=0; i}
cout << a[i] << "\t ";
// jeśli jednak danych w pliku zabraknie, tablica
return 0;
// zostanie uzupełniona przypadkowymi wartościami
}
Wyszukiwarka
Podobne podstrony:
wyklad 7 zap i, 11 2013
wyklad 8 zap i, 11 2013
wyklad 5 zap i, 4 11 2013
Techniki negocjacji i mediacji w administracji wykłady 05 11 2013
wyklad 3 zap i,! 10 2013
Wykład 28 11 2013
wyklad zap i, 12 2013
wyklad zap i, 12 2013
wyklad 9 zap i, 2 12 2013
wyklad 1 zap i, 7 10 2013
wyklad 2 zap i, 10 2013
wyklad 4 zap i,( 10 2013 poprawiony
CHEMIA dla IBM Wyklad 8) 11 2013
6 11 2013 EGIPT W OKRESIE STAREGO I ŚREDNIEGO PAŃSTWA wykład
więcej podobnych podstron