vector<Clock> clocks(3);[ clocks2a.cpp ]
/* populate clocks */
clocks[0] = Clock(true);
clocks[1] = TravelClock(true, "Rome", -1);
clocks[2] = TravelClock(false, "Tokyo", 5);
for (int i = 0; i < clocks.size(); i++)
cout << clocks[i].get_location() << " time: "
<< clocks[i].get_hours() << ":"
<< setw(2) << setfill('0')
<< clocks[i].get_minutes()
<< setfill(' ') << "\n";
Local time is 21:15Защо?
Local time is 21:15
Local time is 9:15
vector<Clock*> clocks(3);Векторът clocks съдържа колекция от различни часовници - указатели към обекти от различни класове. Такава колекция се нарича полиморфна.
/* populate clocks */
clocks[0] = new Clock(true);
clocks[1] = new TravelClock(true, "Rome", -1);
clocks[2] = new TravelClock(false, "Tokyo", 5);
for (int i = 0; i < clocks.size(); i++)
cout << clocks[i]->get_location() << " time: "
<< clocks[i]->get_hours() << ":"
<< setw(2) << setfill('0')
<< clocks[i]->get_minutes()
<< setfill(' ') << "\n";
Local time is 21:15Защо?
Local time is 21:15
Local time is 9:15
class Clock {Ето реализация на цялата програма с динамично свързване:
public:
Clock(bool use_military);
virtual string get_location() const;
virtual int get_hours() const;
int get_minutes() const;
bool is_military() const;
private:
. . .
};
// clocks3.cppРезултатът е:
#include <iostream> #include <iomanip> #include <string> #include <vector> using namespace std; #include "ccc_time.h" class Clock { public: Clock(bool use_military); virtual string get_location() const; virtual int get_hours() const; int get_minutes() const; bool is_military() const; private: bool military; }; Clock::Clock(bool use_military) { military = use_military; } string Clock::get_location() const { return "Local"; } int Clock::get_hours() const { Time now; int hours = now.get_hours(); if (military) return hours; if (hours == 0) return 12; else if (hours > 12) return hours - 12; else return hours; } int Clock::get_minutes() const { Time now; return now.get_minutes(); } bool Clock::is_military() const { return military; } class TravelClock : public Clock { public: TravelClock(bool mil, string loc, int diff); string get_location() const; int get_hours() const; private: string location; int time_difference; }; TravelClock::TravelClock(bool mil, string loc, int diff) : Clock(mil) { location = loc; time_difference = diff; while (time_difference < 0)
time_difference = time_difference + 24; } string TravelClock::get_location() const { return location; } int TravelClock::get_hours() const { int h = Clock::get_hours(); if (is_military()) return (h + time_difference) % 24; else { h = (h + time_difference) % 12; if (h == 0) return 12; else return h; } } int main() { vector<Clock*> clocks(3); clocks[0] = new Clock(true); clocks[1] = new TravelClock(true, "Rome", -1); clocks[2] = new TravelClock(false, "Tokyo", 5); for (int i = 0; i < clocks.size(); i++) { cout << clocks[i]->get_location() << " time: "
<< clocks[i]->get_hours() << ":" << setw(2) << setfill('0')
<< clocks[i]->get_minutes()
<< setfill(' ') << "\n"; } return 0; }
// words.cppПример: Четене на редове.
#include <iostream> #include <string> using namespace std; int main() { int count = 0; string word; while (cin >> word) count++; cout << count << " words.\n"; return 0;
}
С пренасочване на входа програмата words намира броя на думите в текстов файл.
// lines.cpp
#include <iostream>
#include <string>
using namespace std;
int main()
{ int count = 0;
string lines;
while (getline(cin, lines)) count++;
cout << count << " lines.\n";
return 0;
}
С пренасочване на входа програмата lines намира броя на редовете в текстов
файл.
Пример: Четене на символи (букви, цифри и специални символи).// chars.cpp
#include <iostream>
using namespace std;
int main()
{ int count = 0;
char ch;
while (cin.get(ch)) count++;
cout << count << " chars.\n";
return 0;
}
С пренасочване на входа програмата chars намира броя на байтовете на текстов файл.
Четене и запис на текстови файлове.
** В заглавния файл fstream.h
са дефинирани класове, обекти, функции и операции за работа с
файлове.
А) Четене от файл.
* Дефиниране на файлова променлива за четене - обект от класа ifstream:
ifstream inp_data;
* Отваряне на файл от текущата директория с име input.dat:
inp_data.open("input.dat");
* Четене от файл на:
- цели числа и числа с плаваща точка - с операция входен
поток
int n;
double x;
inp_data >> n
>> x;
- низове с операция входен поток и функция getline
string s;
inp_data >>
s; // чете до
разделител
getline(inp_data, s); //
чете цял ред
- символи с член-функция get
char ch;
inp_data.get(ch); // чете един символ
inp_data.unget(); // връща последния
прочетен символ в буфера
* Затваряне на файл
inp_data.close();
// maxval1.cpp
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
/**
Reads numbers from a file and finds the
maximum value
@param in the input stream to read from
@return the maximum value or 0 if the file
has no numbers
*/
double read_data(ifstream& in)
{ double highest;
double next;
if (in >> next) highest = next;
else return 0;
while (in >> next)
if (next > highest) highest =
next;
return highest;
}
int main()
{ string filename;
cout << "Please enter the data file
name: ";
cin >> filename;
ifstream infile;
infile.open(filename.c_str());
if (infile.fail())
{ cout << "Error opening "
<< filename << "\n";
return 1;
}
double max = read_data(infile);
cout << "The maximum value is "
<< max << "\n";
infile.close();
return 0;
}
cin/cout |
файл maxval.txt |
Please enter the data file name: maxval.txt The maximum value is 34399 |
31695 32798.9 25895 26199 34399 29316 24495 23318.04 26632 25795.34 |
Като параметри на функции файловите обекти се обявяват винаги
като параметри-псевдоними.
// readfile.cpp
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
int main()
{ cout << "Enter the file name: ";
string fname;
cin >> fname;
ifstream infile;
infile.open(fname.c_str());
if (infile.fail())
{ cout << "ERROR";
return
1;
}
int sum = 0;
while (!infile.eof())
{ char ch;
infile.get(ch);
if ('0' <= ch
&& ch <= '9') /* it was a digit */
{
infile.unget();
/* oops - didn't want to read it
*/
int n;
infile >>
n;
/* read integer starting with ch */
sum += n;
}
else cout
<< ch;
}
infile.close();
cout << "The sum is "
<< sum << endl;
return 0;
}
cin/cout |
файл first.txt |
nkirov@cpp % ./a.out Enter the file name: first.cpp ERROR% nkirov@cpp % ./a.out Enter the file name: first.txt alabala abc o-o-ops one endend The sum is 359 |
alabala 100abc o-o-ops24 10 1one2 end222end |
Б) Писане във файл.
* дефиниране на файлова променлива за писане - обект от класа ofstream:
ofstream out_data;
* отваряне на файл
out_data.open("output.dat");
Ако в текущата папка
съществува файл с това име, операционната система го изтрива и
създава празен файл с това име.
* писане във файл с:
- изходен поток
int n = 2;
double x = 1.5;
string s = " Hello";
out_data << n
<< " " << x << s;
- член-функция
char ch = 'A';
out_data.put(ch);
* затваряне на файл
out_data.close();
// readwritefiles.cpp
#include <string> #include <iostream> #include <fstream> using namespace std; int main() { cout << "Enter the input file name: "; string finame; cin >> finame; ifstream infile; infile.open(finame.c_str()); if (infile.fail()) { cout << "Error opening " << finame << endl; return 1; } cout << "Enter the output file name: "; string foname; cin >> foname; ofstream outfile; outfile.open(foname.c_str()); if (outfile.fail()) { cout << "Error opening " << foname << endl;; return 1; } while (!infile.eof()) { char ch; infile.get(ch); if ('0' <= ch && ch <= '9') /* it was a digit */ { infile.unget(); /* oops - didn't want to read it */ int n; infile >> n; /* read integer starting with ch */ outfile << n << endl; } else cout << ch; } infile.close(); outfile.close(); return 0; }
cin/cout |
файл first.txt |
файл second.txt |
nkirov@cpp % ./a.out Enter the input file name: first.txt Enter the output file name: second.txt alabala abc o-o-ops one endend |
alabala 100abc o-o-ops24 10 1one2 end222end |
100 24 10 1 2 222 |
* Потоковата библиотека на С++ се състои от няколко класа, свързани в следната йерархия:
* Има още един (най-базов) клас с име ios,
които е базов клас на istream и ostream (и напряк базов клас за всички
други класове в йерархията).
* Обектите cin и cout
са от класове, които са системно зависими и нямат
стандартни имена, но са производни класове съответно на istream и ostream.
Затова можем да дефинираме:
double read_data(istream& in);
и след това да извикаме функцията с параметри от различни
производни на istream класове: .
max = read_data(infile);
max = read_data(cin);
Пример: Четене на числа от файл или стандартен вход, намиране и отпечатване на най-голямото число.
// maxval2.cpp
#include <string> #include <iostream> #include <fstream> using namespace std; /** Reads numbers from a file and finds the maximum value @param in the input stream to read from @return the maximum value or 0 if the file has no numbers */ double read_data(istream& in) { double highest; double next; if (in >> next) highest = next; else return 0; while (in >> next) if (next > highest) highest = next; return highest; } int main() { double max; string input; cout << "Do you want to read from a file? (y/n) "; cin >> input; if (input == "y") { string filename; cout << "Please enter the data file name: "; cin >> filename; ifstream infile; infile.open(filename.c_str()); if (infile.fail()) { cout << "Error opening " << filename << "\n"; return 1; } max = read_data(infile); infile.close(); } else max = read_data(cin); cout << "The maximum value is " << max << "\n"; return 0; }
cin/cout |
файл maxval.txt |
nkirov@cpp % c++ maxval2.cpp nkirov@cpp % ./a.out Do you want to read from a file? (y/n) y Please enter the data file name: maxval.txt The maximum value is 34399 nkirov@cpp % ./a.out Do you want to read from a file? (y/n) n 234 324 100 210 872 300 The maximum value is 872 nkirov@cpp % |
31695 32798.9 25895 26199 34399 29316 24495 23318.04 26632 25795.34 |