
- •1.Краткий обзор агрегатного типа struct.
- •Intcena;
- •Int main()
- •Int cena;
- •Void vyvod(avto s)
- •Int main()
- •3.Понятие объединения union.
- •Void vyvod(avto s, int I)
- •Int main()
- •Intcena;
- •Int main()
- •Int cena;
- •Intmain()
- •Void reset(); …
- •Void Demo::reset() // определениефункции reset( )
- •9.Пример реализации класса для организации обработки символьной строки.
- •Int demochar::length()
- •Int main()
- •10.Пример реализации класса для организации обработки одномерного массива целочисленных значений.
- •11.Инициализация объектов.
- •Int main()
- •12Указатель this.
- •13.Постоянные функции-члены класса.
- •3. Class avto {
- •15. Int main()
- •14.Массив объектов.
- •3. Class avto {
- •24. Int main() {
- •15.Статические переменные-члены и функции-члены класса.
- •17. Staticint GetSumCena() { return SumCena; };
- •19. Staticint SumCena;
- •16 Дружественные функции.
- •8. Friendvoid GetFields(avto&);
- •17 Класс, содержащий переменную-член типа класс.
- •3. Class Date_Avto {
- •16. Class avto {
- •30. Int main()
- •18 Сложность больших программных систем.
- •19 Пять признаков сложной системы.
- •20 Роль декомпозиции, абстракции, иерархии при построении сложных систем.
- •21 Объектная модель.
- •Ood основывается на объектно-ориентированной декомпозиции;
- •25Пример программы с наследованием классов.
- •3. Class avto {
- •18. Class gruz_avto : public avto {
- •36. Int main(){
- •26 Переопределение функций-членов внутри производного класса.
- •3. Class avto {
- •18. Class gruz_avto : public avto {
- •30. Int main()
- •5.Classint_Matrix// класс для обработки целочисленной матрицы
- •45. Int main()
- •Int main()
- •2. Usingnamespace std;
- •3. Int main()
- •18. Return 0;
- •Int main()
- •20. F.Write((char*)&s,sizeof(s));
- •7. Intcena;
- •21. F.Write((char*)&s,sizeof(s)); };
- •22. F.Close();
- •25. F.Seekg(sizeof(s), ios_base::beg);
- •26. F.Read((char*)&s,sizeof(s));
Int main()
{
cout << showpos << setw(15) << setfill('*') << 12.12345
<<';'<< endl;
cout << noshowpos << scientific << uppercase << setfill(' ')
<< setw(15) << setprecision(4) << 12.12345 <<';'<< endl;
cout << setw(15) << left << fixed << 3.12345e+2 <<';'
<< endl;
return 0;
}
34 Файловые потоки в языке С++.
Под файлом подразумевается поименованная совокупность данных на внешнем носителе, например, на винчестере. Логически файл может рассматриваться как конечная последовательность байтов, а потому такие устройства, как дисплей, клавиатуру и принтер также можно рассматривать как частные случаи файлов.
По способу доступа файлы можно разделить на последовательные, чтение и запись в которых производятся с начала байт за байтом, и файлы с произвольным доступом, допускающие чтение и запись в указанную позицию.
В стандартной библиотеке <fstream> языка С++ предусмотрены три класса для работы с файлами:
ifstream — класс входных файловых потоков;
ofstream— класс выходных файловых потоков;
fstream — класс двунаправленных файловых потоков.
Эти три класса являются производными от классов istream, ostream и iostream соответственно, поэтому они наследуют перегруженные операции << и >>, флаги форматирования, манипуляторы, методы.
При работе с файлами в программе могут выполняться следующие операции:
• создание потока;
• открытие потока и связывание его с файлом;
• ввод/вывод данных;
• удаление потока;
• закрытие файла.
Каждый класс файловых потоков содержит конструкторы, с помощью которых можно создавать объекты этих классов различными способами.
Конструкторы без параметров (ifstream(); ofstream(); fstream()) создают объект соответствующего класса, не связывая его с файлом.
Конструкторы с параметрами создают объект соответствующего класса, открывают файл с указанным именем name и связывают файл с объектом:
ifstream (const char* nате, int mode = ios::in):
ofstream (const char* name, int mode = ios::out | ios::trunc):
fstream (constchar * name, int mode = ios::in | ios::out):
Вторым параметром конструктора является режим открытия файла. Если установленное по умолчанию значение не устраивает программиста, можно указать другое, составив его из битовых масок, определенных в классе ios:
enumopen_mode
{
in = 0x01 // открыть для чтения
out = 0x02 // открыть для записи
арр = 0x08 // открыть для добавления в конец
binary = 0x80 // открыть в двоичном режиме
}
35 Основы работы с текстовыми файлами в языке С++.
Текстовый файл в общем случае содержит последовательность строк, каждая из которых завершается специальным символом – признаком конца строки. За последней строкой размещается специальный признак конца файла – end_of_file.
Рассмотрим пример программы, в которой создается текстовый файл, имя которого вводится с клавиатуры. В этот файл записываются 9 строк, и он закрывается. Далее из созданного файла читаются строки и выводятся на экран дисплея.
1. #include<fstream>
2. #include<iostream>
3. usingnamespace std;
4. int main()
5. { char FileName[20];
6. char X[10];
7. cout <<"Vvedite imya FILE : "; cin >> FileName;
8. ofstream F(FileName);
9. for (int i=0; i<3; i++)
10. { cout <<"Vvedite "<< i <<" stroku : "; cin >> X;
11. F << X << endl << i << endl << 1.0/(i+1) << endl; };
12. F.close();
13. cout << endl <<"FILE "<< FileName <<" : \n";
14. ifstream P(FileName);
15. while (! P.eof())
16. {
17. P >> X;
18. cout << X << endl;
19. }
20. P.close();
21. return 0;
22. }
В строке 1 подключается библиотека <fstream>, внутри которой определены три класса ifstream, ofstream и fstream для работы с файлами.
В строке 5 определяется переменная FileName для размещения имени текстового файла на внешнем устройстве.
В строке 6 определяется переменная X, которая фактически будет играть роль логического буфера для обеспечения выполнения операций ввода-вывода при работе с файлами.
В строке 7 выдается запрос на ввод имени файла, и осуществляется ввод имени с клавиатуры.
В строке 8 создается объект Fкласса ofstream, который ассоциируется с текстовым файлом на внешнем устройстве. Соответствующее имя файла на внешнем устройстве содержится в переменной FileName.
В строках 9–11 реализован цикл, при выполнении каждого из 3 шагов которого вводится строка символов, и далее в файл записывается эта введенная строка, номер шага цикла и вещественное значение, вычисленное по формуле 1.0/(i+1).
В стр.12 закрывается файл путем вызова метода close(). Отметим, что когда файл закрывается, то все данные, которые программа писала в него, сбрасываются на диск, и обновляется запись каталога для этого файла. В результате в текущей папке создается текстовый файл, один из вариантов которого показан в следующем окне:
В строке 14 создается объект Pкласса ifstream, который ассоциируется с текстовым файлом на внешнем устройстве, имя которого задается переменнойFileName.
В строках с 15 по 19 включительно организован цикл, в котором считываются все строки файла и выводятся на экран. Цикл завершается при достижении признака конца файла eof. В строке 20 закрывается файл. Отметим, что при достижении конца программы автоматически закрываются все открытые в программе файле.
!!!–1 Если в рассмотренной программе заменить 8 строку ofstreamF(FileName);на строку ofstream F(FileName, ios::app);, то при первом запуске программы будет создаваться текстовый файл, а при следующем обращении к уже существующему файлу будут добавляться новые строки.
!!!–2Если в рассмотренной программе заменить строки: 8. ofstreamF(FileName);на строку fstream F(FileName); 14. ifstreamP(FileName);на строку fstream P(FileName, ios::in); то программа будет работать.
!!!–3 Если в рассмотренной программе заменить 8 строку ofstreamF(FileName);на строку ofstream F(FileName, ios::binary);, то при запуске программы будет создаваться текстовый файл, содержащий 1 строку вида:
В рассмотренной выше программе были использованы два потока F и P. Приведем пример программы, которая вырабатывает абсолютно тот же результат, но при этом мы обойдемся только одним потоком используя метод open() – открыть файл.
1. #include<fstream>
2. #include<iostream>
3. usingnamespace std;
4. int main()
5. { char FileName[20];
6. char X[10];
7. cout <<"Vvedite imya FILE : "; cin >> FileName;
8. fstream F;
9. F.open(FileName,ios::out);
10. for (int i=0; i<3; i++)
11. { cout <<"Vvedite "<< i <<" stroku : "; cin >> X;
12. F << X << endl << i << endl << 1.0/(i+1) << endl; };
13. F.close();
14. cout << endl <<"FILE "<< FileName <<" : \n";
15. F.open(FileName, ios::in);
16. while (! F.eof())
17. {
18. F >> X;
19. cout << X << endl;
20. }
21. F.close();
22. return 0;
23. }
В строке 8 создается поток F типа fstream. В строке 9 с помощью метода open(FileName,ios::out) поток F связывается с текстовым файлом на внешнем устройстве и устанавливается режим записи данных в этот файл. В 10-12 строках в цикле формируется 9 строк текстового файла, а в 13 строке он закрывается.
В 15 строке поток F связывается с текстовым файлом на внешнем устройстве и устанавливается режим чтения данных из этого файла. В 16-20 строках программы организован цикл, в котором последовательно (до тех пор, пока не будет прочитан признак конца файла eof) происходит считывание строк и их вывод на консоль. Затем в 21 строке файл закрывается и далее программа завершается.
36 Обработка текстовых файлов на основе встроенных методов.
Текстовый файл можно сформировать и прочитать посимвольно, используя для этого методы put() и get() соответственно для записи символа в файл и чтения символа из файла.
1. #include<fstream>
2. #include<iostream>
3. usingnamespace std;
4. int main()
5. { char FileName[20];
6. char Ch;
7. cout <<"Vvedite imya FILE : "; cin >> FileName;
8. fstream F;
9. F.open(FileName,ios::out);
10. for (int i=32; i<91; i++) { Ch=i; F.put(Ch); };
11. F.close();
12. cout << endl <<"FILE "<< FileName <<" : \n";
13. F.open(FileName, ios::in);
14. while (F.get(Ch)){ cout << Ch; }
15. F.close();
16. cout << endl;
17. return 0;
18. }
В строке 10 организован цикл, в котором с помощью метода put() осуществляется посимвольная запись в текстовый файл. В 14 строке представлен цикл, обеспечивающий посимвольное чтение с помощью метода get() из текстового файла и вывод на консоль.
В текстовый файл можно записать и можно из него прочитать данные, используя для этого методы соответственно write() и read(). Приведем пример соответствующей программы.
1. #include<fstream>
2. #include<iostream>
3. #include<stdlib.h>
4. usingnamespace std;
5. int main()
6. { char FileName[20]; char X[15];
7. cout <<"Vvedite imya FILE : "; cin >> FileName;
8. ofstream F(FileName, ios::out);
9. for (int i=0; i<3; i++)
10. { cout <<"Vvedite "<< i <<" stroku : "; cin >> X;
11. F.write(X,sizeof(X));
12. _itoa_s(i,X,4,10); F.write(X,sizeof(X));
13. _gcvt(1.0/(i+1),6, X); F.write(X,sizeof(X));
14. };
15. F.close();
16. cout << endl <<"FILE "<< FileName <<" : \n";
17. ifstream P(FileName);
18. while (P.read(X,sizeof(X)))
19. { cout << X << endl; }
20. P.close();
21. return 0;
22. }
В программе формируется файл, в котором, как и в программах пункта 2 этой лекции, трижды записывается триада значений (символьная строка – целочисленное значение – вещественное). Операция записи в файл выполняется на основе использования метода write() (см. стр. 11-13), а считывание из файла реализовано на основе использования метода read() (см. стр. 18).
Отметим, что в строке 3 подключается заголовочный файл stdlib.h для использования в 12 строке функции преобразования _itoa_s(i,X,4,10); целочисленного значения в строковое и для использования в 13 строке функции преобразования _gcvt(1.0/(i+1),6, X); вещественного значения в строковое.
Программой на внешнем устройстве в результате был сформирован файл со следующим содержимым:
37 Основы работы с двоичными файлами в языке С++.
Сохранять данные в файле в языке С++ можно не только в текстовом представлении, но и в двоичном формате. Текстовая форма означает, что все данные, включая числовые, сохраняются в виде текста, который можно легко просмотреть с помощью обычного текстового редактора.
Например, сохранение целочисленного значения 1234567890 в текстовом виде означает сохранение 10 символов-цифр, из которых состоит данное число. Если же сохранить это число в двоичном формате, то оно будет размещаться во внутреннем представлении, т.е. вместо символов сохраняется 32-битное представление числа типа int.
Для значения типа char двоичное представление совпадает с его текстовым — двоичным представлением (например, ASCII-код символа). Для чисел же двоичное представление кардинально отличается от их текстового представления.
У каждого формата хранения данных в файле имеются свои достоинства. Так, текстовые файлы, во-первых, легко читать и редактировать с помощью обычного текстового редактора, во-вторых, можно относительно легко переносить с одной системы на другую.
В двоичном формате вещественные числа сохраняются более точно, поскольку они сохраняются во внутреннем представлении. Обычно сохранение данных в двоичном формате происходит быстрее, поскольку при этом не выполняются соответствующие преобразования, и требуется меньше пространства для хранения (в зависимости от природы данных). Однако при переносе данных с одной систему на другую могут возникать проблемы, в случае если новая система использует другое внутреннее представление данных. При такой ситуации необходимо будет писать программу, которая будет обеспечивать требуемые преобразования данных.
Чтобы сохранить данные в двоичном файле можно воспользоваться методом write(). Этот метод копирует определенное число байтов из памяти в файл, причем он копирует любой тип данных байт в байт, не производя преобразования. Например, если ему передать адрес переменной типа int и указать скопировать 4 байта, то данный метод скопирует 4 байта, передав значение типа int и не производя его преобразования.
Чтобы прочесть информацию из двоичного файла нужно воспользоваться методом read() класса ifstream.
Рассмотрим пример программы, в которой создается двоичный файл. В этот файл записываются значения типа char, int, double, bool и float. Затем из файла читаются эти значения и выводятся на экран.
1. #include<fstream>
2. #include<iostream>
3. usingnamespace std;
4. int main()
5. { char FileName[20];
6. char Ch='Y',Ch2; bool Bo=true,Bo2; int In=1234567890,In2;
7. double Do=123.45,Do2; float Fl=98.75,Fl2;
8. cout <<"Vvedite imya FILE : "; cin >> FileName;
9. ofstream F(FileName, ios::binary);
10. F.write((char*)&Ch,sizeof(Ch));
11. F.write((char*)&In,sizeof(In));
12. F.write((char*)&Do,sizeof(Do));
13. F.write((char*)&Bo,sizeof(Bo));
14. F.write((char*)&Fl,sizeof(Fl));
15. F.close();
16. cout << endl <<"FILE "<< FileName <<" : \n";
17. ifstream P(FileName,ios::binary);
18. P.read((char*)&Ch2,sizeof(Ch2)); cout << Ch2 << endl;
19. P.read((char*)&In2,sizeof(In2)); cout << In2 << endl;
20. P.read((char*)&Do2,sizeof(Do2)); cout << Do2 << endl;
21. P.read((char*)&Bo2,sizeof(Bo2)); cout << Bo2 << endl;
22. P.read((char*)&Fl2,sizeof(Fl2)); cout << Fl2 << endl;
23. P.close();
24. return 0;
25. }
В строке 1 подключается библиотека <fstream>, внутри которой определены три класса ifstream, ofstream и fstream для работы с файлами.
В строке 5 определяется переменная FileName для размещения имени двоичного файла на внешнем устройстве.
В строках 6-7 определяются 10 переменных (5 из которых инициализируются начальными значениями) пяти различных типов.
В строке 8 выдается запрос на ввод имени файла, и осуществляется ввод имени с клавиатуры.
В строке 9 создается объект Fкласса ofstream, который ассоциируется с двоичным файлом на внешнем устройстве. Соответствующее имя файла на внешнем устройстве берется из переменной FileName.
В строках 10–14 в двоичный файл записываются пять разнотипных значений. В 15 строке файл закрывается.
В строке 17 создается объект Pкласса ifstream, который ассоциируется с двоичным файлом на внешнем устройстве, имя которого задается переменнойFileName.
В строках с 18 по 22 включительно с использованием метода read() считывается 5 соответствующих значений из файла. В строке 23 закрывается файл. Отметим, что при достижении конца программы автоматически закрываются все открытые в программе файле.
!!! Если в рассмотренной выше программе заменить строки:
9. ofstream F(FileName);настрокуfstream F(FileName);
17. ifstream P(FileName);настрокуfstream P(FileName, ios::in | ios::binary);,топрограммабудетработать.
В предыдущей программе были использованы два потока F и P. Приведем пример программы, которая использует только один поток. В процессе ее выполнения создается двоичный файл, содержащий 12 целочисленных значений сформированных случайным образом.
1. #include<fstream>
2. #include<iostream>
3. #include<stdlib.h>
4. #include<time.h>
5. usingnamespace std;
6. int main()
7. { char FileName[20];
8. int S, kol_vo=12;
9. cout <<"Vvedite imya FILE : "; cin >> FileName;
10. fstream F(FileName, ios::out | ios::binary);
11. srand((unsigned)time(NULL));
12. for(int i=0; i<kol_vo; i++)
13. {S=rand(); F.write((char*)&S,sizeof(S));};
14. F.close();
15. cout << endl <<"FILE "<< FileName <<" : \n";
16. F.open(FileName,ios::in | ios::binary);
17. while (F.read((char*)&S,sizeof(S))) cout << S << endl;
18. F.close();
19. return 0;
20. }
В строке 8 создается поток F типа fstream, который с помощью метода open(FileName,ios::out | ios::binary) поток F связывается с двоичным файлом на внешнем устройстве и устанавливается режим записи данных в этот файл. В 12-13 строках в цикле с помощью ГСЗ генерируются 12 целых чисел и записываются в двоичный файл, а в 14 строке он закрывается.
В 16 строке поток F связывается с двоичным файлом на внешнем устройстве и устанавливается режим чтения данных из этого файла. В 17 строке организован цикл, в котором последовательно происходит считывание чисел из файла и вывод их на консоль. В 18 строке файл закрывается и далее программа завершается.
38 Обработка двоичных файлов с компонентами типа struct.
Пользователь имеет возможность формировать и обрабатывать двоичные файлы, компоненты которого относятся к агрегатному типу struct. Рассмотрим пример соответствующей программы.
1. #include<fstream>
2. #include<iostream>
3.usingnamespacestd;
4. struct avto
5. { public:
6. avto() { cena=98765; rashod=7.5; }; // конструктор
7. char marka[12];
8. int cena;
9. double rashod;
10. };
11. int main()
12. { char FileName[20]; avto S;
13. cout <<"Vvedite imya FILE : "; cin >> FileName;
14. fstream F(FileName, ios::out | ios::binary);
15. for(int i=0; i<2; i++)
16. { cout << endl;
17. cout <<"Vvedite marku avto: "; cin >> S.marka;
18. cout <<"Vvedite cenu avto: "; cin >> S.cena;
19. cout <<"Vvedite rashod avto: "; cin >> S.rashod;
20. F.write((char*)&S,sizeof(S));
21. };
22. F.close();
23. cout << endl <<"FILE "<< FileName <<" : \n";
24. F.open(FileName,ios::in | ios::binary);
25. while (F.read((char*)&S,sizeof(S))) cout << S.marka <<
26. " "<< S.cena <<" "<< S.rashod << endl;
27. F.close();
28. cout << endl <<"SIZE OBJECT-CLASS avto = "<<
29. sizeof(avto) <<endl;
30.return 0;
31. }
В строке 1 подключается библиотека <fstream>, внутри которой определены три класса ifstream, ofstream и fstream для работы с файлами.
В строках 4-10 описывается агрегатный тип structavto, внутри которого определены явный конструктор и 3 поля.
4. struct avto
5. { public:
6. avto() { cena=98765; rashod=7.5; }; // конструктор
7. char marka[12];
8. int cena;
9. double rashod;
10. };
В строке 12 определяются переменная FileName для размещения имени двоичного файла на внешнем устройстве и переменная S структурного типа avto. В строке 13 обеспечивается ввод имени двоичного файла на внешнем устройстве.
В строке 14 создается поток Fкласса fstream, который ассоциируется с двоичным файлом на внешнем устройстве (имя файла на внешнем устройстве берется из переменной FileName), и настраивается для выполнения вывода в двоичный файл.
В строках 15-21 организован цикл для ввода значений 3 полей структуры S и для записи 2 структурных значений в двоичный файл.
15. for(int i=0; i<2; i++)
16. { cout << endl;
17. cout <<"Vvedite marku avto: "; cin >> S.marka;
18. cout <<"Vvedite cenu avto: "; cin >> S.cena;
19. cout <<"Vvedite rashod avto: "; cin >> S.rashod;