Основи потокового введенню/виводу - бібліотека iostream.h.

Частиною стандартної бібліотеки 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. (У розділі 20.1 ми покажемо, як бібліотека iostream підтримує введення даних, а в розділі 20.5 - як розширити її для введення цих нових типів. Аналогічно розділ 20.2 присвячений підтримці виводу, а розділ 20.4 - розширенню для виведення цих визначених користувачем типів.)

Окрім читання з терміналу і запису на нього, бібліотека 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;

}

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

Введіть ім'я файлу для сортування: alice_emma

Alice Emma has long flowing red hair. Her

Daddy says when the wind blows through her

hair, it looks almost alive, like a fiery

bird in flight. A beautiful fiery bird, he

tells her, magical but untamed. "Daddy, shush, there

is no such creature", she tells him, at

the same time wanting him to tell her

more. Shyly, she asks, "I mean, Daddy, is

there"?

Далі програма виводить у файл outfile відсортовану послідовність рядків. Звичайно, на порядок слів впливають розділові знаки; у наступному розділі ми це виправимо:

""Daddy, "I A Alice Daddy Daddy, Emma Her

Shyly, a alive, almost asks, at beautiful bird

bird, blows but creature", fiery fiery flight. flowing

hair, hair. has he her her her, him

him, in is is it like long looks

magical mean, more. no red same says she

she shush, such tell tells tells the the

there there"? through time to untamed. wanting when

wind

((У розділі 20.6 ми познайомимося з файловим введенням/виводом детальніше.)

Бібліотека iostream підтримує також введення/вивід в область пам'яті, при цьому потік зв'язується з рядком в пам'яті програми. За допомогою потокових операторів введення/виводу ми можемо записувати дані в цей рядок і читати їх звідти. Об'єкт для строкового введення/виводу визначається як екземпляр одного з наступних класів :

istringstream, похідний від istream, читає з рядка;

ostringstream, похідний від ostream, пише в рядок;

stringstream, похідний від iostream, виконує як читання, так і запис.

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

##include <sstream>

((Файл sstream вже включає iostream, так що включати обидва файли необов'язково.) У наступному фрагменті об'єкт класу 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();

}

// ...

}

((У розділі 20.8 ми познайомимося із строковим введенням/виводом детальніше.)

Потоки введення/виводу підтримують два зумовлені типи: 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.