11. cvičení
Procvičování
Na tomto cvičení jsme procvičovali práci se soubory pomocí tříd dostupných ve standardní knihovně. Také jsme procvičili vytváření vlastních struktur/tříd s konstruktory, destruktorem a vlastními metodami.
Příklad na počítání slov jsem vložil do textu k předchozímu cvičení, naopak
příklad na použití třídy std::stringstream
uvádím zde.
Příklad: čtení souřadnic ze souboru
Chceme napsat program, který bude číst souřadnice \((x, y, z)\) ze souboru v následujícím formátu:
1.1 1.2 1.3
2.1 2.2 2.3
3.1 4.2 5.3
6.1 2.2 0.3
(Na každém řádku jsou postupně souřadnice \(x, y, z\) oddělené mezerami, počet řádků dopředu neznáme.)
S využitím operátoru >>
bychom to mohli naprogramovat např. takto:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
ifstream vstup("souradnice.txt");
if (!vstup.good()) {
cout << "soubor neslo otevrit" << endl;
return 1;
}
int pocet = 0;
while (!vstup.eof()) {
double x = 0;
double y = 0;
double z = 0;
vstup >> x >> y >> z;
if (vstup.fail() || vstup.bad()) {
break;
}
pocet++;
}
// kontrola, jak to dopadlo
if (!vstup.eof()) {
cout << "chyba, nedosli jsme az na konec souboru" << endl;
return 1;
}
cout << "pocet bodu je " << pocet << endl;
return 0;
}
Tento program funguje, pokud vstupní soubor obsahuje data přesně podle zadaného formátu. Pokud však na nějakém řádku chybí nebo přebývá nějaké číslo, program to nezpracuje správně – nedokáže rozpoznat, kdy se přejde na další řádek.
Abychom tento problém vyřešili, musíme změnit způsob načítání – místo operátoru
>>
použijeme funkci getline
, což nám umožní rozpoznat data na jednotlivých
řádcích. Další problém ale bude, jak přečíst čísla ze stringu, kde je uložený
daný řádek, protože pro string nemůžeme použít operátor >>
. Problém můžeme
elegantně vyřešit pomocí třídy stringstream z hlavičkového souboru
sstream
, která reprezentuje „virtuální“ stream, do kterého můžeme zapisovat
data pomocí operátoru <<
i z něho číst data pomocí operátoru >>
:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
using namespace std;
int main()
{
ifstream vstup("souradnice.txt");
if (!vstup.good()) {
cout << "soubor neslo otevrit" << endl;
return 1;
}
// 2. zpusob: cteni po radcich
while (!vstup.eof()) {
double x = 0;
double y = 0;
double z = 0;
string radek;
getline(vstup, radek);
if (vstup.fail() || vstup.bad()) {
break;
}
stringstream s;
// zapsat radek do streamu
s << radek;
// precist cisla ze streamu do x, y, z
s >> x >> y >> z;
// kontrola, jestli se to povedlo
if (s.fail() || s.bad()) {
break;
}
pocet++;
}
// kontrola, jak to dopadlo
if (!vstup.eof()) {
cout << "chyba, nedosli jsme az na konec souboru" << endl;
return 1;
}
cout << "pocet bodu je " << pocet << endl;
return 0;
}