Обмен данными между программой и внешними устройствами осуществляется с помощью операций ввода-вывода. Типичным внешним устройством является терминал. На терминале можно напечатать информацию. Можно ввести информацию с терминала, напечатав ее на клавиатуре. Другим типичным устройством является жесткий или гибкий диск, на котором расположены
В языке Си++ нет особых операторов для ввода или вывода данных. Вместо этого имеется набор классов, стандартно поставляемых вместе с компилятором, которые и реализуют основные операции ввода-вывода.
Причиной является как слишком большое разнообразие операций ввода и вывода в разных операционных системах, особенно графических, так и возможность определения новых типов данных в языке Си++. Вывод даже простой строки текста в MS DOS, MS Windows и в X Window настолько различен, что пытаться придумать общие для всех них операторы было бы слишком негибко и на самом деле затруднило бы работу. Что же говорить о классах, определенных программистом, у которых могут быть совершенно специфические требования к их вводу-выводу.
Библиотека классов для ввода-вывода решает две задачи. Во-первых, она обеспечивает эффективный ввод-вывод всех встроенных типов и простое, но тем не менее гибкое, определение операций ввода-вывода для новых типов, разрабатываемых программистом. Во-вторых, сама библиотека позволяет при необходимости развивать её и модифицировать.
В нашу задачу не входит описание программирования в графических системах типа MS Windows. Мы будем рассматривать операции ввода-вывода
Класс istream реализует ostream – iostream.h. Библиотека cout, cin и cerr. cout называется стандартным выводом, cin – стандартным вводом, cerr – стандартным cout и cerr выводят на терминал и принадлежат к классу ostream, cin имеет тип istream и вводит с терминала. Разница между cout и cerr
существенна в Unix – они используют разные дескрипторы для вывода. В других системах они существуют больше для совместимости.
Вывод осуществляется с помощью операции <<, ввод с помощью операции >>. Выражение
cout << "Пример вывода: " << 34;
напечатает на терминале строку "Пример вывода", за которым будет выведено число 34. Выражение
int x; cin >> x;
введет целое число с терминала в переменную x. (Разумеется, для того, чтобы ввод произошел, на терминале нужно напечатать какое-либо число и нажать клавишу возврат каретки.)
В классах iostream операции >> и << определены для всех встроенных типов языка Си++ и для строк (тип char* ). Если мы хотим использовать такую же запись для ввода и вывода других классов, определенных в программе, для них нужно определить эти операции.
class String
{
public:
friend ostream operator<<(ostream os,
const String s);
friend istream operator>>(istream is,
String s);
private:
char* str;
int length;
};
ostream operator<<(ostream os,
const String s)
{
os << s.str;
return os;
}
istream operator>>(istream is,
String s)
{
// предполагается, что строк длиной более
// 1024 байтов не будет
char tmp[1024];
is >> tmp;
if (s.str != 0) {
delete [] s.str;
}
size_t length = strlen(tmp);
s.str = new (std::nothrow) char[length + 1];
if (s.str == 0) {
// обработка ошибок
return is;
}
strcpy(s.str, tmp);
return is;
}
Как показано в примере класса String, операция <<, во-первых, является не методом класса String, а отдельной функцией. Она и не может быть методом класса String, поскольку ее левый операнд – объект класса ostream. С точки зрения записи, она могла бы быть методом класса ostream, но тогда с добавлением нового класса приходилось бы модифицировать класс ostream, что невозможно – каждый бы модифицировал стандартные классы, поставляемые вместе с компилятором. Когда же операция << реализована как отдельная функция, достаточно в каждом новом классе определить ее, и можно использовать запись:
String x; . . . cout << "this is a string: " << x;
Во-вторых, операция << возвращает в качестве результата ссылку на
Аналогично реализована операция ввода. Для класса istream она определена для всех встроенных типов языка Си++ и указателей на строку символов. Если необходимо, чтобы класс, определенный в программе, позволял ввод из >> в качестве функции friend.
Часто бывает необходимо вывести строку или число в определенном формате. Для этого используются так называемые
ostream или istream обрабатывают последующие аргументы
С одним endl. Он вызывает вывод символа новой строки. Другие
endl |
при выводе перейти на новую строку; |
ends |
вывести нулевой байт (признак конца строки символов); |
flush |
немедленно вывести и опустошить все промежуточные буферы; |
dec |
выводить числа в десятичной системе (действует по умолчанию); |
oct |
выводить числа в восьмеричной системе; |
hex |
выводить числа в шестнадцатиричной системе счисления; |
setw (int n) |
установить ширину поля вывода в n символов ( n – целое число); |
setfill(int n) |
установить символ-заполнитель; этим символом выводимое значение будет дополняться до необходимой ширины; |
setprecision(int n) |
установить количество цифр после запятой при выводе вещественных чисел; |
setbase(int n) |
установить систему счисления для вывода чисел; n может принимать значения 0, 2, 8, 10, 16, причем 0 означает систему счисления по умолчанию, т.е. 10. |
Использовать
int x = 53;
cout << "Десятичный вид: " << dec
<< x << endl
<< "Восьмеричный вид: " << oct
<< x << endl
<< "Шестнадцатеричный вид: " << hex
<< x << endl
Аналогично используются
double x; // вывести число в поле общей шириной // 6 символов (3 цифры до запятой, // десятичная точка и 2 цифры после запятой) cout << setw(6) << setprecision(2) << fixed << x << endl;
Те же endl и ends ) могут использоваться и при вводе. В этом случае они описывают представление вводимых чисел. Кроме того, имеется ws. Данный
int x; // ввести шестнадцатеричное число cin >> hex >> x;
Специальным случаем strstream. Отличие этих
Например, в приведенном в предыдущей главе классе Exception для исключительной ситуации можно добавить сообщение. Если мы хотим составить сообщение из нескольких частей, то может возникнуть необходимость форматирования этого сообщения:
// произошла ошибка
strstream ss;
ss << "Ошибка ввода-вывода, регистр: "
<< oct << reg1;
ss << "Системная ошибка номер: " << dec
<< errno << ends;
String msg(ss.str());
ss.rdbuf()->freeze(0);
Exception ex(Exception::INTERNAL_ERROR, msg);
throw ex;
Сначала создается объект типа strstream с именем ss. Затем в созданный ends, который добавил необходимый для символьной строки байтов нулевой байт. Метод str() класса strstream предоставляет доступ к сформатированной строке (тип его возвращаемого значения – char* ). Следующая строка освобождает память, занимаемую Exception с типом ошибки INTERNAL_ERROR и сформированным сообщением и вызывают исключительную ситуацию.
Важное свойство класса strstream состоит в том, что он автоматически выделяет нужное количество памяти для хранения строк. В следующем примере функция split_numbers выделяет числа из строки, состоящей из нескольких чисел, разделенных пробелом, и печатает их по одному на строке.
#include <strstream.h>
void
split_numbers(const char* s)
{
strstream iostr;
iostr << s << ends;
int x;
while (iostr >> x)
cout << x<< endl;
}
int
main()
{
split_numbers("123 34 56 932");
return 1;
}
Замечание. В среде Visual C++ strstream.h.
Как видно из этого примера, независимо от того, какова на самом деле длина входной строки, объект iostr автоматически выделяет память, и при выходе из функции split_numbers, когда объект уничтожается, память будет освобождена.
Однако из данного правила есть одно исключение. Если программа обращается непосредственно к хранимой в объекте строке с помощью метода str (), то объект перестает контролировать эту память, а это означает, что при уничтожении объекта память не будет освобождена. Для того чтобы память все-таки была освобождена, необходимо вызвать метод rdbuf()->freeze(0) (см. предыдущий пример).
Ввод-вывод
Прежде чем перейти к рассмотрению собственно классов, остановимся на том, как осуществляются операции ввода-вывода с
Аналогично происходит запись в
Большинство
В библиотеке Си++ для ввода-вывода ofstream (вывод) и ifstream (ввод). Оба они выведены из класса fstream. Сами операции ввода-вывода выполняются так же, как и для других >> и << определены для класса fstream как "ввести" и "вывести" соответствующее значение. Различия заключаются в том, как создаются объекты и как они привязываются к нужным
При выводе информации в ofstream в виде:
ofstream(const char* szName,
int nMode = ios::out,
int nProt = filebuf::openprot);
Первый аргумент – имя выходного
ios::app |
при записи данные добавляются в конец |
ios:: |
при создании app, запись ведется в текущую позицию; |
ios::in |
|
ios::out |
|
ios::trunc |
если ios::, ios::app или ios::in ; |
ios::binary |
ввод-вывод будет происходить в двоичном виде, по умолчанию используется текстовое представление данных. |
Третий аргумент используется только в том случае, если создается новый
Можно создать open с такими же аргументами, как у предыдущего конструктора:
void open(const char* szName,
int nMode = ios::out,
int nProt = filebuf::openprot);
Только после того, как open ), можно выполнять вывод. Выводятся данные операцией <<. Кроме того, данные можно вывести с помощью методов write или put:
ostream write(const char* pch,
int nCount);
ostream put(char ch);
Метод write выводит указанное количество байтов ( nCount ), расположенных в памяти, начиная с адреса pch. Метод put выводит один байт.
Для того чтобы переместить текущую позицию, используется метод seekp:
ostream seekp(streamoff off,
ios::seek_dir dir);
Первый аргумент – целое число, смещение позиции в байтах. Второй аргумент определяет, откуда отсчитывается смещение; он может принимать одно из трех значений:
ios::beg |
смещение от начала файла |
ios::cur |
смещение от текущей позиции |
ios::end |
смещение от конца файла |
Сместив текущую позицию, операции вывода продолжаются с нового места
После завершения вывода можно выполнить метод close, который выводит внутренние буферы в
Класс ifstream, осуществляющий ввод из ifstream в качестве аргумента конструктора можно задать имя существующего
ifstream(const char* szName, int nMode = ios::in,
int nProt = filebuf::openprot);
Можно воспользоваться стандартным конструктором, а подсоединиться к open.
Чтение из >> или методами read или get:
istream read(char* pch, int nCount); istream get(char rch);
Метод read вводит указанное количество байтов ( nCount ) в память, начиная с адреса pch. Метод get вводит один байт.
Так же, как и для вывода, текущую позицию ввода можно изменить с помощью метода seekp, а по завершении выполнения операций закрыть close или просто уничтожить объект.
Обмен данными между программой и внешними устройствами осуществляется с помощью операций ввода-вывода. Типичным внешним устройством является терминал. На терминале можно напечатать информацию. Можно ввести информацию с терминала, напечатав ее на клавиатуре. Другим типичным устройством является жесткий или гибкий диск, на котором расположены
В языке Си++ нет особых операторов для ввода или вывода данных. Вместо этого имеется набор классов, стандартно поставляемых вместе с компилятором, которые и реализуют основные операции ввода-вывода.
Причиной является как слишком большое разнообразие операций ввода и вывода в разных операционных системах, особенно графических, так и возможность определения новых типов данных в языке Си++. Вывод даже простой строки текста в MS DOS, MS Windows и в X Window настолько различен, что пытаться придумать общие для всех них операторы было бы слишком негибко и на самом деле затруднило бы работу. Что же говорить о классах, определенных программистом, у которых могут быть совершенно специфические требования к их вводу-выводу.
Библиотека классов для ввода-вывода решает две задачи. Во-первых, она обеспечивает эффективный ввод-вывод всех встроенных типов и простое, но тем не менее гибкое, определение операций ввода-вывода для новых типов, разрабатываемых программистом. Во-вторых, сама библиотека позволяет при необходимости развивать её и модифицировать.
В нашу задачу не входит описание программирования в графических системах типа MS Windows. Мы будем рассматривать операции ввода-вывода
Класс istream реализует ostream – iostream.h. Библиотека cout, cin и cerr. cout называется стандартным выводом, cin – стандартным вводом, cerr – стандартным cout и cerr выводят на терминал и принадлежат к классу ostream, cin имеет тип istream и вводит с терминала. Разница между cout и cerr
существенна в Unix – они используют разные дескрипторы для вывода. В других системах они существуют больше для совместимости.
Вывод осуществляется с помощью операции <<, ввод с помощью операции >>. Выражение
cout << "Пример вывода: " << 34;
напечатает на терминале строку "Пример вывода", за которым будет выведено число 34. Выражение
int x; cin >> x;
введет целое число с терминала в переменную x. (Разумеется, для того, чтобы ввод произошел, на терминале нужно напечатать какое-либо число и нажать клавишу возврат каретки.)
В классах iostream операции >> и << определены для всех встроенных типов языка Си++ и для строк (тип char* ). Если мы хотим использовать такую же запись для ввода и вывода других классов, определенных в программе, для них нужно определить эти операции.
class String
{
public:
friend ostream operator<<(ostream os,
const String s);
friend istream operator>>(istream is,
String s);
private:
char* str;
int length;
};
ostream operator<<(ostream os,
const String s)
{
os << s.str;
return os;
}
istream operator>>(istream is,
String s)
{
// предполагается, что строк длиной более
// 1024 байтов не будет
char tmp[1024];
is >> tmp;
if (s.str != 0) {
delete [] s.str;
}
size_t length = strlen(tmp);
s.str = new (std::nothrow) char[length + 1];
if (s.str == 0) {
// обработка ошибок
return is;
}
strcpy(s.str, tmp);
return is;
}
Как показано в примере класса String, операция <<, во-первых, является не методом класса String, а отдельной функцией. Она и не может быть методом класса String, поскольку ее левый операнд – объект класса ostream. С точки зрения записи, она могла бы быть методом класса ostream, но тогда с добавлением нового класса приходилось бы модифицировать класс ostream, что невозможно – каждый бы модифицировал стандартные классы, поставляемые вместе с компилятором. Когда же операция << реализована как отдельная функция, достаточно в каждом новом классе определить ее, и можно использовать запись:
String x; . . . cout << "this is a string: " << x;
Во-вторых, операция << возвращает в качестве результата ссылку на
Аналогично реализована операция ввода. Для класса istream она определена для всех встроенных типов языка Си++ и указателей на строку символов. Если необходимо, чтобы класс, определенный в программе, позволял ввод из >> в качестве функции friend.
Часто бывает необходимо вывести строку или число в определенном формате. Для этого используются так называемые
ostream или istream обрабатывают последующие аргументы
С одним endl. Он вызывает вывод символа новой строки. Другие
endl |
при выводе перейти на новую строку; |
ends |
вывести нулевой байт (признак конца строки символов); |
flush |
немедленно вывести и опустошить все промежуточные буферы; |
dec |
выводить числа в десятичной системе (действует по умолчанию); |
oct |
выводить числа в восьмеричной системе; |
hex |
выводить числа в шестнадцатиричной системе счисления; |
setw (int n) |
установить ширину поля вывода в n символов ( n – целое число); |
setfill(int n) |
установить символ-заполнитель; этим символом выводимое значение будет дополняться до необходимой ширины; |
setprecision(int n) |
установить количество цифр после запятой при выводе вещественных чисел; |
setbase(int n) |
установить систему счисления для вывода чисел; n может принимать значения 0, 2, 8, 10, 16, причем 0 означает систему счисления по умолчанию, т.е. 10. |
Использовать
int x = 53;
cout << "Десятичный вид: " << dec
<< x << endl
<< "Восьмеричный вид: " << oct
<< x << endl
<< "Шестнадцатеричный вид: " << hex
<< x << endl
Аналогично используются
double x; // вывести число в поле общей шириной // 6 символов (3 цифры до запятой, // десятичная точка и 2 цифры после запятой) cout << setw(6) << setprecision(2) << fixed << x << endl;
Те же endl и ends ) могут использоваться и при вводе. В этом случае они описывают представление вводимых чисел. Кроме того, имеется ws. Данный
int x; // ввести шестнадцатеричное число cin >> hex >> x;
Специальным случаем strstream. Отличие этих
Например, в приведенном в предыдущей главе классе Exception для исключительной ситуации можно добавить сообщение. Если мы хотим составить сообщение из нескольких частей, то может возникнуть необходимость форматирования этого сообщения:
// произошла ошибка
strstream ss;
ss << "Ошибка ввода-вывода, регистр: "
<< oct << reg1;
ss << "Системная ошибка номер: " << dec
<< errno << ends;
String msg(ss.str());
ss.rdbuf()->freeze(0);
Exception ex(Exception::INTERNAL_ERROR, msg);
throw ex;
Сначала создается объект типа strstream с именем ss. Затем в созданный ends, который добавил необходимый для символьной строки байтов нулевой байт. Метод str() класса strstream предоставляет доступ к сформатированной строке (тип его возвращаемого значения – char* ). Следующая строка освобождает память, занимаемую Exception с типом ошибки INTERNAL_ERROR и сформированным сообщением и вызывают исключительную ситуацию.
Важное свойство класса strstream состоит в том, что он автоматически выделяет нужное количество памяти для хранения строк. В следующем примере функция split_numbers выделяет числа из строки, состоящей из нескольких чисел, разделенных пробелом, и печатает их по одному на строке.
#include <strstream.h>
void
split_numbers(const char* s)
{
strstream iostr;
iostr << s << ends;
int x;
while (iostr >> x)
cout << x<< endl;
}
int
main()
{
split_numbers("123 34 56 932");
return 1;
}
Замечание. В среде Visual C++ strstream.h.
Как видно из этого примера, независимо от того, какова на самом деле длина входной строки, объект iostr автоматически выделяет память, и при выходе из функции split_numbers, когда объект уничтожается, память будет освобождена.
Однако из данного правила есть одно исключение. Если программа обращается непосредственно к хранимой в объекте строке с помощью метода str (), то объект перестает контролировать эту память, а это означает, что при уничтожении объекта память не будет освобождена. Для того чтобы память все-таки была освобождена, необходимо вызвать метод rdbuf()->freeze(0) (см. предыдущий пример).
Ввод-вывод
Прежде чем перейти к рассмотрению собственно классов, остановимся на том, как осуществляются операции ввода-вывода с
Аналогично происходит запись в
Большинство
В библиотеке Си++ для ввода-вывода ofstream (вывод) и ifstream (ввод). Оба они выведены из класса fstream. Сами операции ввода-вывода выполняются так же, как и для других >> и << определены для класса fstream как "ввести" и "вывести" соответствующее значение. Различия заключаются в том, как создаются объекты и как они привязываются к нужным
При выводе информации в ofstream в виде:
ofstream(const char* szName,
int nMode = ios::out,
int nProt = filebuf::openprot);
Первый аргумент – имя выходного
ios::app |
при записи данные добавляются в конец |
ios:: |
при создании app, запись ведется в текущую позицию; |
ios::in |
|
ios::out |
|
ios::trunc |
если ios::, ios::app или ios::in ; |
ios::binary |
ввод-вывод будет происходить в двоичном виде, по умолчанию используется текстовое представление данных. |
Третий аргумент используется только в том случае, если создается новый
Можно создать open с такими же аргументами, как у предыдущего конструктора:
void open(const char* szName,
int nMode = ios::out,
int nProt = filebuf::openprot);
Только после того, как open ), можно выполнять вывод. Выводятся данные операцией <<. Кроме того, данные можно вывести с помощью методов write или put:
ostream write(const char* pch,
int nCount);
ostream put(char ch);
Метод write выводит указанное количество байтов ( nCount ), расположенных в памяти, начиная с адреса pch. Метод put выводит один байт.
Для того чтобы переместить текущую позицию, используется метод seekp:
ostream seekp(streamoff off,
ios::seek_dir dir);
Первый аргумент – целое число, смещение позиции в байтах. Второй аргумент определяет, откуда отсчитывается смещение; он может принимать одно из трех значений:
ios::beg |
смещение от начала файла |
ios::cur |
смещение от текущей позиции |
ios::end |
смещение от конца файла |
Сместив текущую позицию, операции вывода продолжаются с нового места
После завершения вывода можно выполнить метод close, который выводит внутренние буферы в
Класс ifstream, осуществляющий ввод из ifstream в качестве аргумента конструктора можно задать имя существующего
ifstream(const char* szName, int nMode = ios::in,
int nProt = filebuf::openprot);
Можно воспользоваться стандартным конструктором, а подсоединиться к open.
Чтение из >> или методами read или get:
istream read(char* pch, int nCount); istream get(char rch);
Метод read вводит указанное количество байтов ( nCount ) в память, начиная с адреса pch. Метод get вводит один байт.
Так же, как и для вывода, текущую позицию ввода можно изменить с помощью метода seekp, а по завершении выполнения операций закрыть close или просто уничтожить объект.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.