wyklad nr 6 16 xi


POLITECHNIKA WARSZAWSKA
POLITECHNIKA WARSZAWSKA
Instytut Automatyki i Robotyki
Instytut Automatyki i Robotyki
ZASADY PROGRAMOWANIA KOMPUTERÓW
ZASADY PROGRAMOWANIA KOMPUTERÓW
Język programowania: C/C++
Język programowania: C/C++
Środowisko programistyczne: Builder
Środowisko programistyczne: BuilderC++
C++
Wykład 6 : Struktury i rekordy. Pliki tekstowe.
Wykład 6 : Struktury i rekordy. Pliki tekstowe.
Tablice i rekordy
Tablice i rekordy
Są to złożone struktury danych, które pozwalają za pomocą jednej nazwy
zapamiętać wiele wartości (elementów).
" w tablicy (zmiennej typu tablicowego) - wszystkie elementy muszą być tego
samego typu, rozróżniane są za pomocą indeksów.
" w rekordzie (zmiennej typu struktura) - elementy (pola) rekordu mogą być
różnych typów, rozróżniane są za pomocą nazw.
...
... i n-1
0
indeksy elementów
2
1 -3
a 7
12
nazwy pól typy pól
a[0]
... a[n-1]
... a[i]
tak odwołujemy się do elementów tablicy o nazwie a
imie string
osoba1.imie
nazwisko string
osoba1.nazwisko
plec char
...a tak odwołujemy się
...
dzien int
do pól rekordu o
miesiac int
nazwie osoba1
rok int
...
zarobki double
osoba1.zarobki
jest_w_pracy bool
...
Struktury i rekordy
Struktury i rekordy
REKORDY pozwalają za pomocą jednej nazwy przechowywać wiele elementów
różnych typów. Żeby zdefiniować pojedyncze rekordy, trzeba najpierw
zdefiniować ich strukturę, czy nowy typ danych.
Definicja struktury - czyli typu strukturalnego (inaczej: rekordowego)
struct nazwa struktury {
typ pola nazwa pola, ... nazwa pola; // nazwy pól i ich typ
...
typ pola nazwa pola, ... nazwa pola;
} ; // uwaga - średnik na końcu
Definicja pojedynczych rekordów - czyli zmiennych typu strukturalnego
nazwa struktury nazwa rekordu, ... , nazwa rekordu;
nazwy zmiennych tego typu
typ danych
Desygnator ( oznacznik ) pola rekordu
nazwa rekordu . nazwa pola
tu są kropki
lub
nazwa rekordu . nazwa pola . nazwa pola itd.
Nazwy typów a nazwy zmiennych
Nazwy typów a nazwy zmiennych
" Definiując struktury, czyli nowe typy danych, trzeba bardzo uważać, by nie
pomylić nazwy struktury (czyli nowo zdefiniowanego typu) z nazwą zmiennej
tego typu.
" Aby uniknąć pomyłek, warto nazwy typów strukturalnych rozpoczynać od
wielkiej litery S (jak Struktura) albo T (jak Typ) albo jeszcze inaczej je wyróżniać.
Przykłady:
struct SOsoba {
string imie, nazwisko;
char plec; zdefiniowaliśmy nowy typ danych -
int dzien, miesiac, rok; nową strukturę o nazwie SOsoba;
double zarobki; //pole zarobki jest typu double każde z pól struktury ma podany typ
bool jest_w_pracy;
};
SOsoba osoba1, osoba2, Jancio, szef; // tak definiujemy rekordy - zmienne typu SOsoba
...
cin >> szef.zarobki; a tak odwołujemy się do pól tych rekordów
Jancio.imie= "Jan";
...
cin >> SOsoba.zarobki;
Tak nie wolno ! SOsoba to nie zmienna, tylko typ danych.
SOsoba.plec= M ;
Przykład struktury zagnieżdżonej
Przykład struktury zagnieżdżonej
nazwa typu danych
nazwy pól
// najpierw trzeba zdefiniować strukturę SData:
struct SData {
int dzien, miesiac, rok;
};
// a dopiero teraz można zdefiniować strukturę SOsoba:
struct SOsoba {
string imie, nazwisko;
char plec;
SData data; // tu jest pole o nazwie data, typu SData
double zarobki;
bool jest_w_pracy;
};
SOsoba pracownik; // pracownik jest zmienną typu SOsoba
pracownik.data.rok = 1986;// tak odwołujemy się do pól struktur zagnieżdżonych
Operacje wykonywane na rekordach (i tablicach)
Operacje wykonywane na rekordach (i tablicach)
REKORDY należy wczytywać i drukować odwołując się do kolejnych pól
rekordu, nie wolno tych operacji wykonywać na całych rekordach:
cout << szef.nazwisko << szef.imie << szef.zarobki // drukujemy różne dane szefa (pola)
cout << szef; // nie wolno drukować szefa w całości !
Ta sama zasada odnosi się do TABLIC: wczytujemy i drukujemy kolejne
elementy tablic, a nie tablice w całości:
const n=20;
int i, A[n], B[n];
for (i=0; itablice wczytujemy element po elemencie
cin >> A[i];
cin >> B; // nie wolno wczytywać tablic w całości
B=A; // i nie wolno kopiować całych tablic (podstawiać jednych pod drugie)
UWAGA: inicjowanie rekordów w sposób analogiczny do inicjowania tablic jest
niewskazane, gdyż może być różnie interpretowane przez kompilatory.
Tablice rekordów
Tablice rekordów
REKORDY bardzo często są elementami tablic:
const n=10;
struct Tpunkt {
double x,y; definicja struktury o nazwie Tpunkt
};
Tpunkt P[n], Q[n]; // definicja tablic P i Q zawierających n elementów typu Tpunkt
for (int i=0; icin >> P[i].x >> P[i].y;
for (int i=0; itak nie wolno - nie da się wczytać rekordów w całości
cin >> P[i];
for (int i=0; iQ[i] = P[i];
ale można wykonywać przypisania całych
rekordów, o ile ich polami nie są tablice - na to
Tpunkt schowek = P[1];
należy uważać ! Taka możliwość przypisania nie jest
P[1] = P[n];
więc zbyt bezpieczna.
P[n] = schowek;
Struktury rekordów a klasy obiektów
Struktury rekordów a klasy obiektów
Programowanie strukturalne:
struktura - typ danych
(inaczej: typ strukturalny,
typ rekordowy, wzorzec
struktura
struktury, szablon)
zmienne danego typu
rekord 1 rekord n
rekord 2
. . .
(zmienne strukturalne,
bywają w uproszczeniu,
niezbyt poprawnie,
nazywane strukturami)
Programowanie obiektowe:
klasa - typ danych
klasa
(inaczej: typ obiektowy,
szablon obiektów)
zmienne danego typu
(zmienne obiektowe,
obiekt 1 obiekt n
obiekt 2
. . .
instancje klasy,
egzemplarze klasy)
Pliki tekstowe
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: Jeśli oprócz działań na plikach używamy działań na konsoli poprzez
cin, cout, zalecane jest jawne dołączenie również pliku .
Działania na plikach tekstowych
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
nazwa_pliku - łańcuch określający nazwę fizycznie istniejącego pliku, np. :
"dane.txt " - plik dane.txt w katalogu bieżącym
"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
Wczytywanie danych z pliku
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ć !
Zapisywanie danych do pliku
Zapisywanie danych do pliku
Schemat zapisywania danych do pliku
1. otwieramy plik_wy do zapisu
#include
...
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!)
Dopisywanie do pliku
Dopisywanie do pliku
Schemat dopisywania danych do pliku
#include
ofstream plik_wy (nazwa_pliku, ios::app);
...
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
Zapis danych do pliku
Zapis danych do pliku
Instrukcja zapisywania ( drukowania )
zmienna plikowa << wyrażenie_1 << wyrażenie_2 << ... wyrażenie_n
Każde zapisywane wyrażenie może być jednego z następujących typów:
liczbowy (int, double, ...) char string bool (drukuje się jako 0 lub 1)
Standardowo liczby drukowane są z dokładnością 6 cyfr znaczących w tzw. formacie
ogólnym. Jeżeli liczba nie daje się zapisać z taka ilością cyfr, drukowana jest w postaci
wykładniczej.
Format wydruku (zarówno do pliku, jak i na konsolę) można zmienić na jeden z
następujących:
" format stały (fixed) - w postaci naturalnej, z kropką dziesiętną:
fixed (zmienna plikowa); // ustawia format stały
np.: fixed (cout); // ustawia format stały do zapisu na konsolę (ekran)
" format naukowy (scientific) - w postaci wykładniczej, z literą e:
scientific (zmienna plikowa); // ustawia format naukowy
Format zapisu danych
Format zapisu danych
Precyzję wyświetlania liczb ustawia się następująco:
zmienna plikowa. precison(5);
lub:
zmienna plikowa << setprecision (5);
Co oznacza precyzja?
" dla formatu ogólnego - maksymalną liczbę cyfr
" dla formatu stałego i naukowego - liczbę cyfr po kropce
Szerokość pola wydruku ustawia się następująco:
zmienna plikowa. width (5);
lub:
zmienna plikowa << setw (5);
UWAGA: Wyżej podane funkcje wymagają dołączenia pliku nagłówkowego
Aby uzyskać równej szerokości kolumny w wydruku kolejnych wierszy liczb lub
napisów, należy:
" ustawić stałą szerokość pola wydruku (bardziej ogólne) albo
" zastosować znak tabulacji '\t' po każdej drukowanej wartości.
Zasady czytania z pliku
Zasady czytania z pliku
Instrukcja czytania
zmienna_plikowa >> zmienna_1 >> zmienna_2 ... >> zmienna_n;
Z pliku, podobnie jak i z konsoli (cin >>), można wczytać jedynie zmienne typu:
" liczbowego (int, float, double); liczby oddziela się znakami niewidocznymi.
" znaki (char)
" napisy (string), które można wczytywać dwojako:
" do pierwszego niewidocznego znaku (odstępu, Entera itp.) - jeśli
wczytujemy bezpośrednio do zmiennej typu string
" linia po linii - za pomocą: getline (zmienna plikowa, zmienna typu string);
Funkcja getline wczytuje do zmiennej typu string wszystkie znaki w danym
wierszu aż do napotkania Entera (ale Entera nie dopisuje do tej zmiennej).
Nie można natomiast z pliku ani z konsoli wczytać zmiennej logicznej (typu
bool), ani tablicy (w całości), ani rekordu (w całości).
Przykłady czytania z pliku
Przykłady czytania z pliku
Wczytywanie danych z pliku C:\tablica.txt do tablicy A[n]:
...
int A[n];
ifstream tab ("C:\\tablica.txt ");
// tu powinno być jeszcze sprawdzenie, czy plik istnieje
// ...
for (int i = 0; i < n; i++)
tab >> A[i];
Wczytywanie z pliku kolejnych wierszy oraz drukowanie ich na ekranie:
...
string wiersz;
ifstream dane ("dane.txt");
// tu powinno być jeszcze sprawdzenie, czy plik istnieje
// ...
getline (dane, wiersz); // próba wczytania pierwszego wiersza
while (! dane. eof() ) { // jeśli nie napotkano końca pliku
cout << wiersz << endl; // wydrukuj wczytany wiersz
getline (dane, wiersz); // próba wczytania kolejnego wiersza
}
Przykłady czytania z pliku c.d.
Przykłady czytania z pliku c.d.
Wczytywanie z pliku imion i nazwisk oraz drukowanie ich na ekranie:
string imie, nazwisko;
ifstream dane ("dane.txt");
...
dane >> imie >> nazwisko; // próbuje wczytać z pliku imie i nazwisko
while (! dane. eof() ) {
cout << imie << "\t" << 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.
Sprawdzanie nazwy pliku
Sprawdzanie nazwy pliku
Uwaga: w przypadku czytania danych
z pliku i dopisywania do pliku,
plik o podanej nazwie musi istnieć!
Aby sprawdzić, czy dany plik dał się otworzyć, korzysta się z funkcji good():
dane. open (... );
do strumienia cerr
if ( !dane. good() ) {
wysyła się komunikaty o
cerr << "Blad otwarcia pliku " << endl ;
błędach (jest to odrębny
else {
rodzaj strumienia, obok
... // dalej działania na plikach
cin i cout)
// i cala reszta programu
}
Wczytywanie nazwy pliku
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


Wyszukiwarka

Podobne podstrony:
wyklad nr 5 2 xi
wyklad nr 8 0 xi
wyklad nr 7 # xi
ZARZĄDZANIE WARTOŚCIĄ PRZEDSIĘBIORSTWA Z DNIA 26 MARZEC 2011 WYKŁAD NR 3
Zarzadzanie strategiczne wyklad nr 2
wyklad nr 2 PK
Wykład nr 6 Decyzja
wyklad nr 4 & x
SS wyklad nr 6 ppt
Sem 4 Wykład nr 9 Interakcje 2013
AUDYT WEWNĘTRZNY Z DNIA 26 LUTY 2011 WYKŁAD NR 1
WYKŁAD NR 5 HYDRAULIKA i HYDROLOGIA (PDF)
wykład nr 6
Wyklad nr 8
WYKŁAD NR 3
Wykład nr 3
OP wyklad nr 4
ET DI2 ObwodySygnaly2 wyklad nr 9 10 czworniki aktywne
Prezentacja Wykład nr 5

więcej podobnych podstron