Потоковый ввод/вывод данных. Класс string.
Лабораторная работа № 2
Частью стандартной библиотеки C++ является библиотека iostream – объектно-ориентированная иерархия классов, где используется и множественное, и виртуальное наследование. В ней реализована поддержка для файлового ввода/вывода данных встроенных типов. Кроме того, разработчики классов могут расширять эту библиотеку для чтения и записи новых типов данных.
Для использования библиотеки iostream в программе необходимо включить заголовочный файл
#include <iostream>
Операции ввода/вывода выполняются с помощью классов istream (потоковый ввод) и ostream (потоковый вывод). Третий класс, iostream, является производным от них и поддерживает двунаправленный ввод/вывод. Для удобства в библиотеке определены три стандартных объекта-потока:
cin – объект класса istream, соответствующий стандартному вводу. В общем случае он позволяет читать данные с терминала пользователя;
cout – объект класса ostream, соответствующий стандартному выводу. В общем случае он позволяет выводить данные на терминал пользователя;
cerr – объект класса ostream, соответствующий стандартному выводу для ошибок. В этот поток мы направляем сообщения об ошибках программы.
Вывод осуществляется, как правило, с помощью перегруженного оператора сдвига влево (<<), а ввод – с помощью оператора сдвига вправо (>>):
#include <iostream>
#include <string>
int main()
{
string in_string;
// вывести литерал на терминал пользователя
cout << "Введите свое имя, пожалуйста: ";
// прочитать ответ пользователя в in_string
cin >> in_string;
if ( in_string.empty() )
// вывести сообщение об ошибке на терминал пользователя
cerr << "ошибка: введенная строка пуста!\n";
else cout << "Привет, " << in_string << "!\n";
}
Назначение операторов легче запомнить, если считать, что каждый "указывает" в сторону перемещения данных. Например,
>> x
перемещает данные в x, а
<< x
перемещает данные из x.
Помимо чтения с терминала и записи на него, библиотека iostream поддерживает чтение и запись в файлы. Для этого предназначены следующие классы:
ifstream, производный от istream, связывает ввод программы с файлом;
ofstream, производный от ostream, связывает вывод программы с файлом;
fstream, производный от iostream, связывает как ввод, так и вывод программы с файлом.
Чтобы использовать часть библиотеки iostream, связанную с файловым вводом/выводом, необходимо включить в программу заголовочный файл
#include <fstream>
Файловый ввод/вывод поддерживается теми же операторами:
#include <fstream>
#include <string>
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;
while ( infile >> buffer ) {
text.push_back( buffer );
outfile<<buffer << "\n" ;
}
return 0;
}
Библиотека iostream поддерживает также ввод/вывод в область памяти, при этом поток связывается со строкой в памяти программы. С помощью потоковых операторов ввода/вывода мы можем записывать данные в эту строку и читать их оттуда. Объект для строкового ввода/вывода определяется как экземпляр одного из следующих классов:
istringstream, производный от istream, читает из строки;
ostringstream, производный от ostream, пишет в строку;
stringstream, производный от iostream, выполняет как чтение, так и запись.
Для использования любого из этих классов в программу нужно включить заголовочный файл
#include <sstream>
В следующем фрагменте объект класса ostringstream используется для форматирования сообщения об ошибке, которое возвращается вызывающей программе.
#include <sstream>
string program_name( "our_program" );
string version("0.01");
// ...
string mumble( int *array, int size )
{
if ( ! array ) {
ostringstream out_message;
out_message << "ошибка: "
<< program_name << "--" << version
<< ": " << __FILE__ << ": " << __LINE__
<< " -- указатель равен 0; "
<< " а должен адресовать массив.\n";
// возвращаем строку, в которой находится сообщение
return out_message.str();
}
}
Потоки ввода/вывода поддерживают два предопределенных типа: char и wchar_t. В этой главе мы расскажем только о чтении и записи в потоки данных типа char. Помимо них, в библиотеке iostream имеется набор классов и объектов для работы с типом wchar_t. Они отличаются от соответствующих классов, использующих тип char, наличием префикса ‘w’. Так, объект стандартного ввода называется wcin, стандартного вывода – wcout, стандартного вывода для ошибок – wcerr. Но набор заголовочных файлов для char и wchar_t один и тот же.
Классы для ввода/вывода данных типа wchar_t называются wostream, wistream, wiostream, для файлового ввода/вывода – wofstream, wifstream, wfstream, а для строкового – wostringstream, wistringstream, wstringstream.