Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Простой пример






Предположим, к примеру, у вас есть класс computer_screen:

class computer_screen

{
public:
computer_screen(char *, long, int, int);
void show_screen(void);
private:
char type[32];
long colors;
int x_resolution;
int y_resolution;
};

Предположим, что у вас есть также класс mother_board:

class mother_board

{
public:
mother_board(int, int, int);
void show_mother_board(void);
private:
int processor;
int speed;
int RAM;
};

Используя эти два класса, можно породить класс computer, что показано ниже:

class computer: public computer_screen, public mother_board

{
public:
computer(char *, int, float, char *, long, int, int, int, int, int);
void show_computer(void);
private:
char name[64];
int hard_disk;
float floppy;
};

Как видите, этот класс указывает свои базовые классы сразу после двоеточия, следующего за именем класса computer.

 

При использовании наследования в C++ для порождения одного класса из другого возможны ситуации, когда вы порождаете свой класс из класса, который уже, в свою очередь, является производным от некоторого базового класса. Например, предположим, вам необходимо использовать класс сотputer базовый для порождения класса workstation, как показано ниже:

class work_station: public computer

{
public:
work_station (char *operating_system, char *name, int hard_disk, float floppy, char *screen, long colors, int x_res, int y_res, int processor, int speed, int RAM);
void show_work_station(void);
private:
char operating_system[64];
};

Конструктор класса workstation просто вызывает конструктор класса computer, который в свою очередь вызывает конструкторы классов сотрuter_screen и mother_board:

work_station:: work_station(char *operating_system, char *name, int hard_disk, float floppy, char *screen, long colors, int x_res, int y_res, int processor, int speed, int RAM): computer (name, hard_disk, floppy, screen, colors, x_res, y_res, processor, speed, RAM)

{
strcpy(work_station:: operating_system, operating_system);
}

В данном случае класс computer выступает в роли базового класса. Однако вы знаете, что класс computer был порожден из классов computer_screen и mother_board. В результате класс work_station наследует характеристики всех трех классов. На рис. 27 показано, что порождение классов приводит к иерархии классов.

Рис. 27. Построение иерархии классов.

В следующем примере класс Z наследует оба класса X и Y:

#include < iostream.h>
class X {
protected:
int a;
public:
void make_a(int i) { a = i; }
};
class Y {
protected:
int b;
public:
void make_b(int i) { b = i; }
};
// Z наследует как от X, так и от Y
class Z: public X, public Y {
public:
int make_ab() { return a*b; }
};
int main()
{
Z i;
i.make_a(10);
i.make_b(12);
cout < < i.make_ab();
return 0;
}

Поскольку класс Z наследует оба класса X и Y, то он имеет доступ к публичным и защищенным членам обоих классов X и Y.

В предыдущем примере ни один из классов не содержал конструкторов. Однако ситуация ста­новится более сложной, когда базовый класс содержит конструктор. Например, изменим преды­дущий пример таким образом, чтобы классы X, Y и Z содержали конструкторы:

#include < iostream.h>
class X {
protected:
int a;
public:
X() {
a = 10;
cout < < " Initializing X\n";
}
};
class Y {
protected:
int b;
public:
Y() {
cout < < " Initializing Y\n";
b = 20;
}
};
// Z наследует как от X, так и от Y
class Z: public X, public Y {
public:
Z() { cout < < " Initializing Z\n"; }
int make_ab() { return a*b; }
};
int main()
{
Z i;
cout < < i.make_ab();
return 0;
}

Программа выдаст на экран следующий результат:

Initializing X
Initializing Y
Initializing Z
200

Обратим внимание, что конструкторы базовых классов вызываются в том порядке, в котором они указаны в списке при объявлении класса Z.

В общем случае, когда используется список базовых классов, их конструкторы вызываются сле­ва направо. Деструкторы вызываются в обратном порядке — справа налево.

 

ПОТОКИ ВВОДА ВЫВОДА

2.2 Потоки ввода-вывода В C++ существует несколько классов потоков: Класс streambuf управляет буфером потока, обеспечивая базовые операции заполнения, опорожнения, сброса и прочих манипуляций с буфером. Класс ios является базовым классом потоков ввода-вывода. Классы istream и ostream – производные от ios и обеспечивают работу потоков соответственно ввода и вывода. Класс iostream является производным от двух предыдущих и предусматривает функции, как для ввода, так и для вывода. Классы ifstream, ofstream и fstream предназначены для управления файловым вводом-выводом. Классы istrstream и ostrstream управляют резидентными потоками (форматированием строк в памяти). Для работы с потоками необходимо подключить заголовочный файл. Кроме того, может потребоваться подключить файлы (файловый ввод-вывод), (параметризованные манипуляторы) и (форматирование в памяти). Библиотека ввода-вывода C++ предусматривает четыре предопределенных объекта-потока, связанных со стандартными входным и выходным устройствами.


Имя Класс Описание

cin istream Ассоциируется со стандартным вводом (клавиатурой).

cout ostream Ассоциируется со стандартным выводом (экраном).

cerr ostream Ассоциируется со стандартным устройством ошибок (экраном) без буферизации.

clog ostream Ассоциируется со стандартным устройством ошибок (экраном)с буферизацией.

 

iostream — заголовочный файл с классами, функциями и переменными для организации ввода-вывода в языке программирования C++. Он включён в стандартную библиотеку C++. Название образовано от Input/Output Stream («поток ввода-вывода»). В языке C++ и его предшественнике, языке программирования Си, нет встроенной поддержки ввода-вывода, вместо этого используется библиотека функций. iostream управляет вводом-выводом, как и stdio.h в Си. iostream использует объекты cin, cout, cerr и clog для передачи информации в и из стандартных потоков ввода, вывода, ошибок (без буферизации) и ошибок (с буферизацией) соответственно. Являясь частью стандартной библиотеки C++, эти объекты также являются частью стандартного пространства имён — std.

Некоторые новые компиляторы (например, компилятор Visual C++ из Visual Studio.NET 2003[1]) старые библиотеки< iostream.h> больше не поддерживают, вместо них нужно использовать только новые: #include < iostream>.

Частью стандартной библиотеки C++ является библиотека iostream – объектно-ориентированная иерархия классов, где используется и множественное, и виртуальное наследование. В ней реализована поддержка для файлового ввода/вывода данных встроенных типов. Кроме того, разработчики классов могут расширять эту библиотеку для чтения и записи новых типов данных.

Для использования библиотеки iostream в программе необходимо включить заголовочный файл

#include < iostream>

 

Помимо чтения с терминала и записи на него, библиотека iostream поддерживает чтение и запись в файлы. Для этого предназначены следующие классы:

  • ifstream, производный от istream, связывает ввод программы с файлом;
  • ofstream, производный от ostream, связывает вывод программы с файлом;
  • fstream, производный от iostream, связывает как ввод, так и вывод программы с файлом.

Чтобы использовать часть библиотеки iostream, связанную с файловым вводом/выводом, необходимо включить в программу заголовочный файл

#include < fstream>

 

(Файл fstream уже включает iostream, так что включать оба файла необязательно.) Файловый ввод/вывод поддерживается теми же операторами:

#include < fstream> #include < string> #include < vector> #include < algorithm> int main(){ string ifile; cout < " Введите имя файла для сортировки: "; cin > > ifile; // сконструировать объект класса ifstream для ввода из файла ifstream infile(ifile.c_str()); if (! infile) { cerr < " ошибка: не могу открыть входной файл: " < ifile < endl; return -1; } string ofile = ifile + ".sort"; // сконструировать объект класса ofstream для вывода в файл ofstream outfile(ofile.c_str()); if (! outfile) { cerr < < " ошибка: не могу открыть выходной файл: " < < ofile < < endl; return -2; } string buffer; vector< string, allocator > text; int cnt = 1; while (infile > > buffer) { text.push_back(buffer); cout < < buffer < < (cnt++ % 8? " ": " \n"); } sort(text.begin(), text.end()); // выводим отсортированное множество слов в файл vector< string >:: iterator iter = text.begin(); for (cnt = 1; iter! = text.end(); ++iter, ++cnt) outfile < < *iter < < (cnt % 8? " ": " \n"); return 0; }

 

СТАНДАРТНЫЕ ПОТОКИ ДЛЯ БАЗОВЫХ ТИПОВ

КЛАСС IOS_BASE

Объект класса ios_base хранит сведения о форматировании, которое состоит из:

· Формат флагов в объект типа fmtflags.

· Маска исключения в объект типа iostate.

· Ширина поля в объект типа int.

· Точность отображения в объект типа int.

· Языковой стандарт объекта в объект типа язык.

· Два расширяемый массива с элементами типа длинные и void указателя.

 

Требования

Заголовок: < ios>

Пространство имён: std

Форматирование. к началу статьи Формат выводимых данных задается с помощью достаточно большого числа флагов, но мы остановимся на наиболее полезных. Да, чуть не забыл, флаги устанавливаются с помощью метода setf(fmtflags) и сбрасываются методом unsetf(fmtflags) (это методы потоковых классов). oct, dec, hex – вывод чисел в восьмеричной, десятеричной и шестнадцатеричной системах счисления соответственно. Рассмотрим предыдущий пример, слегка изменив его:
int i; cout< < " Input i: "; cin> > i; cout.setf(ios:: oct); cout< < " i = " < < i< < endl;
Теперь если Вы введете 8, то увидите на экране “i = 10”. uppercase – вывод символа е (при выводе чисел в научной нотации) и x (при выводе чисел в шестнадцатеричной системе счисления) в верхнем регистре. showpos – если установлен, то перед положительными числами в десятеричной системе счисления будет ставиться знак +. left, right – выравнивание. showpoint – появление десятичной точки и последующих нулей при выводе вещественных чисел. Например:
float i; cout< < " Input i: "; cin> > i; cout.setf(ios:: showpoint); cout< < " i = " < < i< < endl; getch();
showbase – вывод основания системы счисления. scientific, fixed – установка вывода чисел в научной нотации или с фиксированной точкой.
float i; cout< < " Input i: "; cin> > i; cout.setf(ios:: scientific); cout< < " i = " < < i< < endl; cout.setf(ios:: fixed); cout< < " i = " < < i< < endl;
boolalpha – булевые значения выводятся как true или false. Установку нескольких флагов можно объединить в один вызов setf():
cout.setf(ios:: showbase | ios:: showpos);
Так же для форматирования используются следующие методы потоков – width(), precision() и fill(). width() – задаёт число знаков отводимое под выводимое число. precision() – задает сколько знаков после запятой будет выводиться у вещественных чисел fill() – задает какими символами будут заполняться неиспользованные позиции в строке вывода. Сейчас рассмотрим пример, и все будет ясно как день:
cout.setf(ios:: fixed); cout.width(10); cout.precision(3); cout.fill('%'); cout.setf(ios:: right); cout< < 12.3456< < endl; cout.width(10); cout.precision(3); cout.fill('%'); cout.setf(ios:: left); cout< < 12.3456< < endl;
на экран выведется:
%%%%12.345 12.345%%%%

 

Режимы открытия файлов

Режимы открытия файлов устанавливают характер использования файлов. Для установки режима в классе ios_base предусмотрены константы, которые определяют режим открытия файлов (см. Таблица 1).

 

Таблица 1 — режимы открытия файлов
Константа Описание
ios_base:: in открыть файл для чтения
ios_base:: out открыть файл для записи
ios_base:: ate при открытии переместить указатель в конец файла
ios_base:: app открыть файл для записи в конец файла
ios_base:: trunc удалить содержимое файла, если он существует
ios_base:: binary открытие файла в двоичном режиме

 

ofstream fout(" cppstudio.txt", ios_base:: app); // открываем файл для добавления информации к концу файла

fout.open(" cppstudio.txt", ios_base:: app); // открываем файл для добавления информации к концу файла

 

Режимы открытия файлов можно комбинировать с помощью поразрядной логической операции или |, например: ios_base:: out | ios_base:: trunc - открытие файла для записи, предварительно очистив его.

Объекты класса ofstream, при связке с файлами по умолчанию содержат режимы открытия файлов ios_base:: out | ios_base:: trunc. То есть файл будет создан, если не существует. Если же файл существует, то его содержимое будет удалено, а сам файл будет готов к записи. Объекты класса ifstreamсвязываясь с файлом, имеют по умолчанию режим открытия файла ios_base:: in - файл открыт только для чтения. Режим открытия файла ещё называют — флаг, для удобочитаемости в дальнейшем будем использовать именно этот термин. В таблице 1 перечислены далеко не все флаги, но для начала этих должно хватить.

Обратите внимание на то, что флаги ateиappпо описанию очень похожи, они оба перемещают указатель в конец файла, но флаг app позволяет производить запись, только в конец файла, а флаг ate просто переставляет флаг в конец файла и не ограничивает места записи.

ofstream fout(" F: \\ Test.txt", std:: ios_base:: ate);

 

При работе с ofstream к любому флагу добавляется std:: ios_base:: out

Т.е. если написать,

Код C++
  ofstream fout(" F: \\Test.txt", std:: ios_base:: ate);
 

то фактически получим

Код C++
  ofstream fout(" F: \\Test.txt", std:: ios_base:: ate | std:: ios_base:: out);
 

 

ofstream fout(" F: \\ Test.txt", ios_base:: app); fout < < " HELLO"; fout.seekp(2); fout < < 'a'; //результат HELLOa

 

 

Если нужно дописать что-то в существующий файл в произвольное место, то подойдет
std:: ios_base:: in | std:: ios_base:: out

 

Код C++
  ofstream fout(" F: \\Test.txt", std:: ios_base:: in); fout < < " HELLO"; fout.seekp(2); fout < < 'a'; //результат HEaLO
 

 

#include < string> #include < fstream> #include < iostream>

#include < iostream>

ФАЙЛОВЫЕ ПОТОКИ. ОТКРЫТИЕ/ЗАКРЫТИЕ ФАЙЛА

В С++ все операции, связанные с файловыми потоками, определены в fstream. Поэтому в разделе директив необходимо указать #include < fstream>.

Для открытия файла необходимо его связать с потоком. В С++ имеются три вида потоков:

· ifsteam – входной поток. Используется только для чтения информации из файла;

· ofsream – выходной поток. Используется только для вывода информации в файл;

· fstream – двунаправленный поток. Используется для чтения и записи в файл.

 

Открытие файла выполняется с помощью функции open(). При открытии можно указать способ открытия файла: открытие для дозаписи информации в конец файла, открытие бинарного файла, открытие только для чтения или только для записи и др.

Например, если необходимо открыть бинарный файл «text» для чтения и записи, то следует записать:

1. fstream file;

2.

3. < file.open(“text”, ios:: binary || ios:: in || ios:: out);

Функция open() при успешном открытии файла вернет значение TRUE, в противном случае, если файл не будет открыт по каким-то причинам, вернет значение FALSE.

Поэтому для проверки открытия файла рекомендуется использовать оператор if:

1. if(! file) cout< < “Не удается открыть файл”; return 1;

 

После работы с файлом его следует закрыть, особенно это важно, если выполнялись операции записи в файл. Закрытие файла выполняется с помощью функции close(): file.close();

Файл (file) – именованная совокупность данных, находящаяся на внешнем устройстве и имеющая определенные атрибуты (характеристики).

Поток (srteam) – абстрактный канал связи, создаваемый в программе для обмена данными.

 

1. Связать его с файлом данных и открыть (open) для работы в определенном режиме:

void ifstream:: open(const char *имя_файла, openmode режим=ios:: in);

void ofstream:: open(const char *имя_файла,
openmode режим=ios:: out|ios:: trunc);

 

void fstream:: open(const char *имя_файла,
openmode режим=ios:: in|ios:: out);

где имя_файла – имя файла, в которое может входить спецификатор пути;

режим – задает режим открытия файла, может принимать значения:

Режим Краткое описание
ios:: app Добавление в конец файла. Только для файлов открываемых для вывода.
ios:: ate Поиск конца файла при его открытии. Операции ввода/вывода могут быть выполнены в любом месте файла.
ios:: binary Открытие файла в двоичном режиме. По умолчанию все файлы открываются в текстовом режиме.
ios:: in Открытие файла для ввода
ios:: out Открытие файла для вывода
ios:: trunc Удаление содержимого ранее существовавшего файла с тем же названием и усечению его до 0 длины. При создании потока ofstreamлюбой ранее существовавший файл с тем же именем автоматически усекается до 0 длины

 

Ввод-вывод в поток можно реализовать с помощью операторов < < и > >. При этом информация форматируется также, как и на экране. При считывании строк можно использовать методы get и getline.

С помощью функции bool eof (); можно определить, был ли достигнут конец файла ввода.

1. Для закрытия потока используется функция close().

 

РАБОТА С ТЕКСТОВЫМИ ФАЙЛАМИ

Файлы позволяют пользователю считывать большие объемы данных непосредственно с диска, не вводя их с клавиатуры. Существуют два основных типа файлов: текстовые и двоичные.

Текстовыми называются файлы, состоящие из любых символов. Они организуются по строкам, каждая из которых заканчивается символом «конца строки». Конец самого файла обозначается символом «конца файла». При записи информации в текстовый файл, просмотреть который можно с помощью любого текстового редактора, все данные преобразуются к символьному типу и хранятся в символьном виде.

 

Для работы с файлами используются специальные типы данных, называемые потоками. Поток ifstream служит для работы с файлами в режиме чтения, а ofstream в режиме записи. Для работы с файлами в режиме как записи, так и чтения служит поток fstream.

В программах на C++ при работе с текстовыми файлами необходимо подключать библиотеки iostream и fstream.

Для того чтобы записывать данные в текстовый файл, необходимо:

1. описать переменную типа ofstream.

2. открыть файл с помощью функции open.

3. вывести информацию в файл.

4. обязательно закрыть файл.

Для считывания данных из текстового файла, необходимо:

1. описать переменную типа ifstream.

2. открыть файл с помощью функции open.

3. считать информацию из файла, при считывании каждой порции данных необходимо проверять, достигнут ли конец файла.

4. закрыть файл.

 

Запись информации в текстовый файл

Как было сказано ранее, для того чтобы начать работать с текстовым файлом, необходимо описать переменную типа ofstream. Например, так:

ofstream F;

Будет создана переменная F для записи информации в файл. На следующим этапе файл необходимо открыть для записи. В общем случае оператор открытия потока будет иметь вид:

F. open («file», mode);

Здесь F — переменная, описанная как ofstream, file — полное имя файла на диске, mode — режим работы с открываемым файлом. Обратите внимание на то, что при указании полного имени файла нужно ставить двойной слеш. Для обращения, например к файлу accounts.txt, находящемуся в папке sites на диске D, в программе необходимо указать: D: \\sites\\accounts.txt.

Файл может быть открыт в одном из следующих режимов:

· ios:: in — открыть файл в режиме чтения данных; режим является режимом по умолчанию для потоков ifstream;

· ios:: out — открыть файл в режиме записи данных (при этом информация о существующем файле уничтожается); режим является режимом по умолчанию для потоков ofstream;

· ios:: app — открыть файл в режиме записи данных в конец файла;

· ios:: ate — передвинуться в конец уже открытого файла;

· ios:: trunc — очистить файл, это же происходит в режиме ios:: out;

· ios:: nocreate — не выполнять операцию открытия файла, если он не существует;

· ios:: noreplace — не открывать существующий файл.

 

Параметр mode может отсутствовать, в этом случае файл открывается в режиме по умолчанию для данного потока.

После удачного открытия файла (в любом режиме) в переменной F будет храниться true, в противном случае false. Это позволит проверить корректность операции открытия файла.

Открыть файл (в качестве примера возьмем файл D: \\sites\\accounts.txt) в режиме записи можно одним из следующих способов:

 

//первый способ
ofstream F;
F.open(" D: \\sites\< strong> \< /strong> accounts< strong>.< /strong> txt", ios:: out);
//второй способ, режим ios:: out является режимом по умолчанию
//для потока ofstream
ofstream F;
F.open(" D: \\game\\noobs.txt");
//третий способ объединяет описание переменной и типа поток
//и открытие файла в одном операторе
ofstream F (" D: \\game\\noobs.txt", ios:: out);

После открытия файла в режиме записи будет создан пустой файл, в который можно будет записывать информацию.

Если вы хотите открыть существующий файл в режиме дозаписи, то в качестве режима следует использовать значение ios:: app.

 

После открытия файла в режиме записи, в него можно писать точно так же, как и на экран, только вместо стандартного устройства вывода cout необходимо указать имя открытого файла.

Например, для записи в поток F переменной a, оператор вывода будет иметь вид:

F< < a;

 

Для последовательного вывода в поток G переменных b, c, d оператор вывода станет таким:

G< < b< < c< < d;

Закрытие потока осуществляется с помощью оператора:

F.close();

 

Создать текстовый файл D: \\sites\\accounts.txt и записать в него n вещественных чисел.






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.