ЧТЕНИЕ ИЗ ВХОДНОГО ФАЙЛОВОГО ПОТОКА



Потоковые классы.

Поток это абстрактное понятие, относящееся к любому переносу данных от источника к приемнику. Потоки С++, в отличие от функций ввода/вывода в сти­ле С, обеспечивают надежную работу как со стандартными, так и с определен­ными пользователем типами данных, а также единообразный и понятный син­таксис.

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

По направлению обмена потоки можно разделить на входные(данные вводятся в память), выходные(данные выводятся из памяти) и двунаправленные (допускаю­щие как извлечение, так и включение).

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

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

Для поддержки потоков библиотека С++ содержит иерархию классов, построен­ную на основе двух базовых классов — ios и streambuf. Класс ios содержит общие для ввода и вывода поля и методы, класс streambuf обеспечивает буферизацию потоков и их взаимодействие с физическими устройствами. От этих классов на­следуется класс istream для входных потоков и ostream — для выходных. Два последних класса являются базовыми для класса iostream, реализующего двуна­правленные потоки. Ниже в иерархии классов располагаются файловые и стро­ковые потоки. Далее перечислены часто используемые классы потоков.

ios          — базовый класс потоков;

istream         — класс входных потоков;

ostream       — класс выходных потоков;

iostream  — класс двунаправленных потоков;

istringstream — класс входных строковых потоков;

ostringrstream — класс выходных строковых потоков;

stringstream — класс двунаправленных строковых потоков;

ifstream    — класс входных файловых потоков;

ofstream   — класс выходных файловых потоков;

fstream     — класс двунаправленных файловых потоков.

 

Описания классов находятся в заголовочных файлах:

<ios>         — базовый класс потоков ввода/вывода;

<iosfwd>   — предварительные объявления средств ввода/вывода;

<istream>   — шаблон потока ввода;

<ostream> — шаблон потока вывода;

<iostream> — стандартные объекты и операции спотоками ввода/вывода;

<fstream>  — потоки ввода/вывода в файлы;

<sstream>  — потоки ввода/вывода в строки;

<streambuf> — буферизация потоков ввода/вывода;

Подключение к программе файлов <fstream> и <sstream> автоматически подклю­чает и файл <iostream>, так как он является для них базовым.

Стандартные потоки.

Заголовочный файл <iostream> содержит, кроме описания классов для ввода/вы­вода, четыре предопределенных объекта:

Объект Класс Описание
cin istream Связывается с клавиатурой (стандартным буферизованным вводом)
cout ostream Связывается с экраном (стандартным буферизованным выводом)
сеrr ostream Связывается с экраном (стандартным нсбуферизованпым выводом), куда направляются сообщения об ошибках
clog ostream Связывается с экраном (стандартным буферизованным выводом), куда направляются сообщения об ошибках

Эти объекты создаются при включении с программу заголовочного файла <iostream>, при этом становятся доступными связанные с ними средства вво­да/вывода. Имена этих объектов можно переназначить на другие файлы или символьные буферы.

В классах istream и ostream операции извлечения из потока >>ипомещения в по­ток << определены путем перегрузки операций сдвига.

Пример:

#include <iostream>

int main(){

int i;

cin >> i;

cout << "Вы ввели " << i;

return 0;

}

Операции извлечения и чтения в качестве результата своего выполнения форми­руют ссылку на объект типа istream для извлечения и ссылку на ostream — для чтения. Это позволяет формировать цепочки операций, что проиллюстрировано последним оператором приведенного примера. Вывод при этом выполняется сле­ва направо.

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

// Скобки не требуются - приоритет сложения больше, чем << :

cout << i + j;

//Скобки необходимы - приоритет операции отношения

//меньше, чем << :

cout << (i < j):

cout << (i << j):    // Правая операция << означает сдвиг

Величины при вводе должны разделяться пробельными символами (пробелами, знаками табуляции или перевода строки). Извлечение прекращается, если оче­редной символ оказался недопустимым. Если в операции помещения в поток встречается выражение, изменяющее не­которую переменную, то она не должна присутствовать в цепочке операций бо­лее одного раза, поскольку в таком случае результат может зависеть от реализа­ции компилятора.

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

#include <iostream> 1nt main(){

int i = 0xD;    double d;

// Символы из потока ввода преобразуются в double:

cin >> d:

// int и double преобразуются в строку символов:

cout << i << ' ' << d;

return 0;}

Рассмотрим, как обрабатываются с помощью этих операций данные различных типов.

Числовые значенияможно вводить в десятичной или шестнадцатеричной системе счисления (с префиксом 0х) со знаком или без знака. Вещественные числа пред­ставляются в форме с фиксированной точкой или с порядком. Например, если для предыдущего примера с клавиатуры вводится последовательность символов 1.53e-2, она интерпретируется как вещественное число с порядком и преобразу­ется во внутреннее представление, соответствующее типу double. При выводе вы­полняется обратное преобразование, и на экран выводятся символы:

 0.0153

Поскольку ввод буферизован, помещение в буфер ввода происходит после нажа­тия клавиши перевода строки, после чего из буфера выполняется операция из­влечения из потока. Это дает возможность исправлять введенные символы до того, как нажата клавиша Enter.

При вводе строкизвлечение происходит до ближайшего пробела (вместо него в строку заносится нуль-символ):

char str1[100], str2[100];

cin >> str1>> str2;

Если с клавиатуры вводится строка "раз два три четыре пять", переменные strl и str2 примут значения "раз" и "два" соответственно, а остаток строки воспринят не будет. При необходимости ввести из входного потока строку целиком (до сим­вола '\n') пользуются методами get или getline.

Значения указателейвыводятся в шестнадцатеричной системе счисления. Под лю­бую величину при выводе отводится столько позиций, сколько требуется для ее представления. Чтобы отделить одну величину от другой, используются пробелы:

cout<< i << ' ' << d << "   " << j;

Методы обмена с потоками

В потоковых классах наряду с операциями извлечения >> и включения << опре­делены методы для неформатированного чтения и записи в поток (при этом пре­образования данных не выполняются).

Ниже приведены функции чтения, определенные в классе istream.

gcount()- возвращает количество символов, считанных с помощью последней функции неформатированного ввода;

get()- возвращает код извлеченного из потока символа или EOF;

get(c) - возвращает ссылку на поток, из которого выполнялось чтение, и записывает извлеченный символ в с;

get(buf, num, lim= '\n')- считывает num-l символов (или пока не встретится символ lim) и копирует их в символьную строку buf. Вместо символа lim в строку записывается признак конца строки ('\0'). Символ lim остается в по­токе. Возвращает ссылку на текущий поток;

getline(buf, num, lim='\n') - аналогична функции get, но копирует в buf и сим­вол lim;

ignore(num = 1, 1im = EOF) - считывает и пропускает символы до тех пор, пока не будет прочитано num символов или не встретится разделитель, заданный параметром lim. Возвращает ссылку на текущий поток;

peek() - возвращает следующий символ без удаления его из потока или EOF, если достигнут конец файла;

putback(c) - помещает в поток символ с, который становится текущим при извлечении из потока;

read(buf, num) - считывает num символов (или все символы до конца файла, если их меньше num) в символьный массив buf и возвращает ссылку па текущий поток;

readsome(buf, num) - считывает num символов (или все символы до конца файла, если их меньше num) в символьный мас­сив buf и возвращает количество считанных символов;

seekg(pos) - устанавливает текущую позицию чтения в позицию pos;

seekg(offs, org) - перемещает текущую позицию чтения на offs байтов, считая от одной из трех позиций, определяе­мых параметром org: ios::beg (от начала файла), ios::cur (от текущей позиции) или ios::end (от конца файла);

tellg() - возвращает текущую позицию чтения потока;

unget() - помещает последний прочитанный символ в поток и возвращает ссылку на текущий поток.

В классе ostream определены аналогичные функции для неформатированного вы­вода:

flush() -  записывает содержимое потока вывода на физическое устройство;

put(c) - выводит в поток символ с и возвращает ссылку на поток;

seekg(pos) - устанавливает текущую позицию записи в значение pos;

seekg (offs, org) - перемещает текущую позицию записи па offs байтов, читая от одной из трех позиций, определяемых параметром org: ios::beg (от начала файла), ios::cur (от текущей позиции) или ios: :end (от конца файла);

tellg() - возвращает текущую позицию записи потока;

write(buf, num) - записывает в поток num символов из массива buf и возвраща­ет ссылку на поток.

Пример.Программа считывает строки из входного потока в символьный мас­сив.

#include <iostream>

int main(){const int N = 20; Len = 100; char str[Len][N]; int i = 0;

while (cin.getline(str[i], Len, '\n') &&i<N){

// ...

i++;} return 0;}

 

Файловые операции В/В в C++

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

Основные концепции:

  • Используя выходной файловый поток, можно писать информацию в файл с помощью оператора вставки (<<).
  • Используя входной файловый поток, можно читать хранимую в файле информацию с помощью оператора извлечения (>>).
  • Для открытия и закрытия файла используются методы файловых классов.
  • Для чтения и записи файловых данных можно использовать операторы вставки и извлечения, а также некоторые методы файловых классов.

ВЫВОД В ФАЙЛОВЫЙ ПОТОК

Команда cout представляет собой объект типа ostream (выходной поток). Используя класс ostream, программы могут выполнять вывод в cout с использованием оператора вставки или различных методов класса, например cout.put. Заголовочный файл iostream определяет выходной поток cout. Аналогично, заголовочный файл istream определяет класс выходного файлового потока с именем ofstream. Используя объекты класса ofstream, ваши программы могут выполнять вывод в файл. Для начала вы должны объявить объект типа ofstream, указав имя требуемого выходного файла как символьную строку, что показано ниже:

ofstream file_object("FILENAME.EXT");

Если имя файла указывается при объявлении объекта типа ofstream, C++ создаст новый файл на диске, используя указанное имя, или перезапишет файл с таким же именем, если он уже существует. Следующая программа создает объект типа ofstream и затем использует оператор вставки для вывода нескольких строк текста в файл BOOKINFO.DAT:

#include <fstream>

void main(void)

{
ofstream book_file("BOOKINFO.DAT");
book_file << "Учимся программировать на языке C++, " << "Вторая редакция" << endl;
book_file << "Jamsa Press" << endl;
book_file << "22.95" << endl;
}

В данном случае программа открывает файл BOOKINFO.DAT и затем записывает три строки в файл, используя оператор вставки.

ЧТЕНИЕ ИЗ ВХОДНОГО ФАЙЛОВОГО ПОТОКА

Используя класс ofstream, программы могут быстро выполнить операции вывода в файл. Подобным образом программы могут выполнить операции ввода из файла, используя объекты типа ifstream. Опять же, вы просто создаете объект, передавая ему в качестве параметра требуемое имя файла:

ifstream input_file("filename.EXT");

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

#include <iostream>

#include <fstream>

void main(void)

{
ifstream input_file("BOOKINFO.DAT") ;
char one[64], two[64], three[64];
input_file >> one;
input_file >> two;
input_file >> three;
cout << one << endl;
cout << two << endl;
cout << three << endl;
}

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

С:\> FILE_IN <ENTER>

Учимся

Программировать

на


Дата добавления: 2018-02-15; просмотров: 402; ЗАКАЗАТЬ РАБОТУ