ЧТЕНИЕ ИЗ ВХОДНОГО ФАЙЛОВОГО ПОТОКА
Потоковые классы.
Поток — это абстрактное понятие, относящееся к любому переносу данных от источника к приемнику. Потоки С++, в отличие от функций ввода/вывода в стиле С, обеспечивают надежную работу как со стандартными, так и с определенными пользователем типами данных, а также единообразный и понятный синтаксис.
Чтение данных из потока называется извлечением, вывод в поток — помещением, или включением. Поток определяется как последовательность байтов и не зависит от конкретного устройства, с которым производится обмен (оперативная память, файл на диске, клавиатура или принтер). Обмен с потоком для увеличения скорости передачи данных производится, как правило, через специальную область оперативной памяти — буфер. Фактическая передача данных выполняется при выводе после заполнения буфера, а при вводе — если буфер исчерпан.
По направлению обмена потоки можно разделить на входные(данные вводятся в память), выходные(данные выводятся из памяти) и двунаправленные (допускающие как извлечение, так и включение).
По виду устройств, с которыми работает поток, можно разделить потоки на стандартные, файловые и строковые.
Стандартные потокипредназначены для передачи данных от клавиатуры и на экран дисплея, файловые потоки — для обмена информацией с файлами на внешних носителях данных (например, на магнитном диске), а строковые потоки — для работы с массивами символов в оперативной памяти.
|
|
Для поддержки потоков библиотека С++ содержит иерархию классов, построенную на основе двух базовых классов — 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; просмотров: 1386; Мы поможем в написании вашей работы! |

Мы поможем в написании ваших работ!