Для определения момента достижения конца файла можно использовать функцию-член eof(), имеющую следующий прототип:
int eof();
При достижении конца файла она возвращает ненулевое число, в противном случае возвращается ноль.
Система ввода/вывода C++ позволяет осуществлять произвольный доступ с использованием функции seekg() и seekp(). Их наиболее употребительной формой является следующая:
Здесь тип streamoff определен в заголовочном файле iostream.h. Он определяет область значений, которые может принимать величина offset. В настоящее время streamoff определен с помощью оператора typedef как long.
Система ввода/вывода C++ обрабатывает два указателя, ассоциированные с каждым файлом. Один из них, get pointer, определяет, где именно в файле будет производиться следующая операция чтения. Другой указатель put pointer указывает, где именно в файле будет производиться следующая операция записи. Всякий раз, когда осуществляются операции ввода или вывода, соответствующий указатель автоматически перемещается. С помощью функций seekg() и seekp() можно получить доступ к файлу в произвольном месте.
Функция seekg() перемещает указатель get pointer на число байт offset от заданного origin, принимающего одно из следующих трех значений:
Величина Значение
ios::beg Начало файла
ios::cur Текущее положение
ios::end Конец файла
Функция seekp() перемещает указатель put pointer на offset байт от заданного origin, в качестве которого служит одно из указанных выше значений.
Следующая программа демонстрирует использование функции seekp(). Она позволяет указать имя файла в командной строке, после которого следует указать, какой именно байт в файле надо заменить. Затем функция пишет символ “x” в указанную позицию. Следует обратить внимание, что файл должен быть открыт для выполнения операций чтения и записи.
Следующая программа использует функцию seekg() для того, чтобы вывести содержимое файла, начиная с позиции, указываемой в командной строке:
#include <iostream.h>
#include <fstream.h>
int main(int argc, char *argv[])
{
char ch;
if(argc != 3) return 1;
ifstream in(argv[1], ios::in | ios::binary);
if (!in) return 1;
in.seekg(atoi(argv[2]), ios::beg);
while(in.get(ch)) cout << ch;
in.сlоse();
return 0;
}
Можно определить текущую позицию файлового указателя, используя следующие функции:
streampos tellg();
streampos tellp();
Здесь тип streampos определен в заголовочном файле iostream.h. В текущей версии он определен с помощью функции typedef как long.
Как можно видеть, система ввода/вывода C++ является одновременно и мощной и гибкой. В этой главе мы рассмотрели некоторые наиболее употребительные функции, хотя C++ включает несколько других важных функций. Например, стоит, вероятно, познакомиться с функцией getline() (определенной istream) и различными формами перегруженных функций ввода/вывода.
Глава 8. Ввод/вывод в массивы
В дополнение к вводу/выводу на консоль и в файлы, система ввода/вывода языка C++ позволяет осуществлять ввод/вывод в массивы. Ввод/вывод на основе массивов использует память в качестве устройства для ввода и вывода. Ввод/вывод на основе массивов осуществляется с помощью обычных потоков C++. Фактически вся представленная в предыдущей главе информация применима к вводу/выводу на основе массивов. Единственное, что отличает ввод/вывод на основе массивов, заключается в том, что связанным с потоком устройством служит память.
В некоторой литературе по C++ ввод/вывод на основе массивов (array-based I/O) называют также вводом/выводом в память (in-RAM I/O). Поскольку потоки способны форматировать информацию, то иногда ввод/вывод на основе массивов называют также форматированием в памяти (in-RAM formatting).
Вывод на основе массивов C++ подобен использованию функций sprintf() и sscanf() в языке С. В обоих случаях память используется в качестве устройства для ввода и вывода.
Для использования ввода/вывода на основе массивов необходимо включить в программу заголовочный файл strstrea.h.
8.1 Классы ввода/вывода в массивы
Классами для ввода/вывода на основе массивов являются istrstream, ostrstream и strstream. Эти классы используются для создания потоков ввода, вывода и ввода/вывода соответственно. Класс istrstream имеет в качестве базового класса istream. Класс ostrstream порожден от класса ostream, а класс strstream – от класса iostream. Поэтому все классы для вывода на основе массивов имеют доступ к тем же функциям, что и «нормальные» классы ввода/вывода.