Учись программированию на C++ Builder бесплатно!

Операции поместить в поток (<<) и взять из потока (>>) предназначены для работы с потоками, как со стандартными потоками cout и cin, используемыми в основном в консольных приложениях, так и с файлами. Приведенные ниже примеры будут ориентированы на то, что создается файловый поток outfile для вывода данных и файловый поток infile для чтения данных. Для этого должны быть выполнены операторы:

 

#include <fstream.h>
ofstream outfile("Test.dat"); // создание потока outfile, связанного с файлом "Test.dat"
if (!outfile) {
ShowMessage("Файл не удается создать");
return;
}

... // операторы поместить в поток
outfile.close(); // закрытие файла
ifstream infile ("Test.dat"); // создание потока infile, связанного с файлом "Test.dat"
if (!infile) {
ShowMessage("Файл не удается открыть");
return;
}

... // операторы взять их потока
infile.close(); // закрытие файла

Вывод в потоки может быть выполнен с помощью операции поместить в поток, т.е. перегруженной операции <<. Операция << перегружена для вывода элементов данных встроенных типов, для вывода строк и вывода значений указателей. Она позволяет также с помощью манипуляторов потока осуществлять вывод целых чисел в десятичном, восьмеричном и шестнадцатеричном форматах, вывод значений с плавающей запятой с различной точностью, с указанием по выводу десятичной точки, в экспоненциальном формате или в формате с фиксированной точкой, вывод данных с выравниваем относительно какой-либо границы поля указанной ширины, вывод данных с полями, заполненными заданными символами, вывод буквами в верхнем регистре в экспоненциальном формате и при выводе шестнадцатеричных чисел.

Операция << помещает в поток, являющийся ее первым операндом, аргумент, являющийся ее вторым операндом. Размещение в потоке происходит в текстовом виде. Например, оператор:

outfile << "Привет!";

поместит в файл текст «Привет!». Операторы:

 

int i = 25;
outfile << i;

поместят в файл текст «25».

Операция << возвращает ссылку на объект своего первого операнда, т.е. на поток. Это позволяет использовать сцепленные операции поместить в поток, например, оператор:

outfile << "2*2= " << (2 * 2);

поместит в файл текст «2*2 = 4». Это произойдет потому, что левая операция << поместит текст «2 * 2 = » и вернет outfile, после чего правая операция << будет иметь вид:

outfile << (2 * 2);

и добавит к тексту результат своего правого операнда.

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

 

char sin [80];
ofstream outfile("Test.dat");
if(!outfile) {
ShowMessage("Файл не удается создать");
return;
}
// операторы записи в файл, например:
outfile << "2 * 2 = " << 2 * 2; // закрытие файла
outfile.close();
// открытие файла как входного потока
ifstream infile("Test.dat") ;
if (Unfile) {
ShowMessage("Файл не удается открыть");
return;
}
Memo1->Clear();
while(!infile.eof())
{
infile.getline(s1,80);
Memo1->Lines->Add(AnsiString(s1));
}
// закрытие файла
infile.close();

Смысл их сводится к тому, что создается файл «Test.dat», связанный с потоком outfile, затем в него заносится операциями << некоторый текст, после чего файл закрывается. Затем он опять открывается, связываясь с потоком infile, и строки из него считываются и переносятся в окно Memo1.

Последовательное применение операций поместить в поток (сцепленных или задаваемых самостоятельными операторами) приводит к занесению текстов в одну строку, как в рассмотренном выше примере. Если требуется перейти на новую строку, то можно или ввести в текст символ конца строки '\n' или применить манипулятор потока endl (сокращение от end line - конец строки). Например, операторы:

outfile << "2 * 2 :\n" << (2 * 2) << "\n";
outfile << "2 * 2 :" << endl << (2 * 2) << endl;

дадут один и тот же результат: первая строка будет содержать текст «2 * 2 :», вторая «4», а курсор файла будет переведен на третью строку.

В предыдущих примерах выводились константы и константные выражения. При выводе переменных все работает точно так же. Например, операторы:

 

int i = 25, j = 2;
outfile << i << " * " << j << " = " << (i * j) << endl;

и операторы:

 

int i = 25, j = 2;
char s [80] = "25 * 2 = ";
outfile << s << (i * j) << endl;

выводят в файл один и тот же текст: «25 * 2 = 50».

Предыдущий пример показывает, что вывод строки типа char * осуществляется просто записью в качестве правого операнда указателя на эту строку. Однако для строк типа AnsiString операция << не перегружена. Поэтому при выводе таких строк надо использовать приведение ее к типу char * с помощью метода c_str:

 

AnsiString sa = "Это строка AnsiString";
outfile << sa.c_str() << endl;

При выводе могут использоваться и достаточно сложные выражения. В приведенном ниже примере предполагается наличие двух окон редактирования Edit1 и Edit2, в которые пользователь вводит целые числа, а программа выводит результат их сравнения:

 

int i = StrToInt(Edit1->Text);
int j = StrToInt(Edit2->Text);
outfile << i << (i == j ? " " : " не ") << "равно " << j << endl;

В зависимости от введенных чисел будет выведен текст «... равно ...» или «... не равно ...».

Обратите внимание на то, что условный оператор заключен в скобки. Это необходимо делать, поскольку операция поместить в поток имеет сравнительно высокий приоритет и без скобок она применилась бы только к переменной i, что вызвало бы сообщение о синтаксической ошибке.

Операция << позволяет выводить и указатели. Например, можно написать оператор:

outfile << Memo1 endl;

и он выведет текст типа «0063F610» – шестнадцатеричный адрес объекта Memo1. Особым приемом надо выводить при необходимости указатель на строку типа char *. Если записать в операции поместить в поток сам указатель, например, s, то выведется не указатель, а содержимое строки. Так перегружена операция << при выводе строк. Если же нужен именно адрес, то перед именем указателя надо поместить операцию приведения типа (void *). Например:

outfile << (void *)s << endl;

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

Эта операция >> извлекает данные из потока, заданного ее левым операндом, и заносит их в переменную, заданную правым операндом. Операция возвращает поток, указанный как ее левый операнд. Благодаря этому допускаются сцепленные операции взять из потока. Например, оператор:

infile >> i >> j;

прочтет, начиная с текущей позиции файла, связанного с потоком infile, два целых числа в переменные i и j. Если в текущей позиции файла первому из чисел предшествуют пробельные символы или разделители, то они будут пропущены. За окончание числа операция примет первый отличный от цифры символ, в частности, пробельный. Поэтому, если эти два числа были ранее записаны в файл например, оператором:

outfile << i << '  ' << j << endl;

то они прочтутся нормально. Но если они были записаны оператором:

outfile << i << j << endl;

т.е. без пробела, то их цифры будут слиты вместе и это составное число прочтется как i, а при чтении j произойдет ошибка.

Операцией >> можно вводить из файла строки в переменные типа char *. Например, операторы:

 

char s[80];
infile >> s;

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

Если при выполнении операции взять из потока считывается символ конца потока, то операция возвращает 0. Этим можно воспользоваться, чтобы, например, читать все содержимое файла, разбитое на лексемы:

while (infile >> s1)
{
...
}

 

Поделиться