Проверка состояния файла и потока

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

Успешность выполнения открытия потока можно проверить с помощью метода is_open, определенного в классах ifstream, ofstream, fstream. Его прототип:

bool is_open (); // true – поток связан с открытым файлом, false - нет

Проверка правильности открытия файла для входного файлового потока f1:

if (!f1.is_open())

cout << "Input file can't be opened.\n";

При неуспешном открытии файла связанному с ним потоку присваивается нулевое значение, поэтому эта же проверка может быть записана и так:

if (!f1)

cout << "Input file can't be opened.\n";

Определить, достигнут ли конец входного файла, можно при помощи метода eof, являющегося методом класса ios, а, следовательно, и методом класса ifstream. Его прототип:

bool eof(); // true – конец файла достигнут, false - нет

При использовании этого метода следует иметь в виду, что он возвращает значение true, только в случае, если к моменту его вызова конец файла был реально обнаружен. Например, когда при чтении разделенных пробелами чисел из текстового файла конец файла для последнего числа "выступил" в роли ограничителя. Если же, скажем, после последнего числа в текстовом файле содержится еще один символ-разделитель, именно он явится ограничителем и метод eof начнет возвращать значение true только после следующего чтения файла.

Функции (методы) ввода-вывода

Кроме переопределенных операций << и >>, классы istream и ostream, содержат несколько специальных методов для ввода-вывода информации. Поскольку классы файлового ввода-вывода являются "потомками" этих классов, данные методы применимы как для стандартных, так и для файловых потоков.

Методы get и put

Для посимвольного (побайтового) ввода предназначен метод get, его наиболее часто используемая форма:

istream& get (char& ch);

Для посимвольного (побайтового) вывода предназначен метод put:

ostream& put (char ch);

Метод get, имеющий один параметр, читает один символ (байт) из входного потока в переменную ch. При выполнении этих методов символы-разделители (пробелы, табуляции, переход на новую строку) не пропускаются, а читаются так же, как и другие символы потока.

Метод put, имеющий один параметр, выводит в выходной поток один символ (байт) – значение переменной ch.

ofstream f6("d:\\test.txt");

char c1;

сin.get(c1); // чтение символа с клавиатуры в переменную c1

f6.put(c1); // вывод значения символьной переменной c1 в выходной поток f6

Есть еще несколько форм метода get, например:

istream& get (char *buf, streamsize num);

istream& get (char *buf, streamsize num, char delim);

int get();

где streamsize – разновидность типа int. Первые две из этих форм get позволяют читать из входного потока в область ввода, адресуемую указателем buf, несколько (до num-1 или до конца файла) символов за одно обращение. Окончание ввода вызывает также обнаружение символа перехода на новую строку (кода клавиши "Enter") – для первой формы, и символа delim – для второй. Эти символы из входного потока не извлекаются, они остаются в потоке до выполнения следующей операции ввода. После прочитанных в область ввода buf символов первая и вторая формы метода get записывают завершающий строку нулевой символ.

Третья форма метода get читает из входного потока очередной символ, если при этом обнаруживается конец файла, то возвращаемым значением является признак конца файла – константа EOF, представляющая собой целое отрицательное число.

Отметим, что в отличие от ввода символов с помощью операции >>, при использовании метода get пробельные символы воспринимаются как обычные символы, а не как разделители.

Метод getline

Для ввода строк предусмотрен также метод getline, имеющий две формы – с двумя и тремя параметрами.

istream& getline (char *buf, streamsize num);

istream& getline (char *buf, streamsize num, char delim);

где streamsize – разновидность типа int. Первый параметр – это адрес области памяти для ввода данных, второй – увеличенное на 1 максимальное число вводимых символов, возможный третий – символ-ограничитель, ввод которого прекращает чтение вне зависимости от числа введенных символов. Метод getline считывает символы из входного потока в область ввода, адресуемую указателем buf, до тех пор, пока их число не достигнет num-1 или не встретится конец файла. Кроме того, прекращение чтения для первой формы вызывает символ перехода на новую строку (код клавиши "Enter" ('\n' или '\xA'), а для второй формы – символ, указанный в списке фактических параметров в качестве delim. Эти символы извлекаются из входного потока, но в область ввода не записываются. После прочитанных в область ввода buf символов обе формы метода getline записывают завершающий строку нулевой символ.

Легко заметить сходство метода функции getline с методом get, имеющим несколько параметров. Различие их состоит в том, что getline удаляет из входного потока символ перехода на новую строку (код клавиши "Enter"), а get, как и операция >>, – нет.

Методы read и write

Для ввода-вывода нескольких байтов данных определены также методы read иwrite:

istream& read (char* buf, int nCount);

ostream& write (const char* buf, int nCount);

Метод read вводит указанное в nCount количество байтов (символов) в память, начиная с адреса buf. Метод writeвыводит указанное в nCount количество байтов (символов), расположенных в памяти, начиная с адреса buf.