Примеры по работе с файлами

Некоторые другие функции управления потоками ввода-вывода

Статус потоков ввода-вывода

Потоки ввода-вывода после выполнения каждой операции ввода-вывода находятся в определенном состоянии, характеризующимся, так называемым, статусом потока. Статус потока ввода-вывода представляет собой перечисление, имеющее следующие значения:

· ios:: goodbit – нормальное состояние потока – ошибки отсутствуют;

· ios:: eofbit – достигнут конец файла;

· ios:: failbit – исправимая ошибка;

· ios:: bedbit – неисправимая ошибка.

Значение статуса после завершения очередной операции ввода-вывода можно узнать с помощью функции rdstate (), которая возвращает значение одного из перечисленных выше значений:

fstream File (……..);

while (File.rdstate () = ios:: goodbit)

{

// Выполняем очередную операцию с файлом

}

Еще один способ узнать значение статуса потока ввода-вывода состоит в использовании одной из следующих функций потока, возвращающих значение true, при установке соответствующего флага статуса:

· bool good ()

· bool eof () – эту функцию мы уже использовали раньше

· bool fail ()

· bool bed ()

Например:

fstream File (……..);

while (File.good ())

{

// Выполняем очередную операцию с файлом

}

Если после выполнения очередной операции ввода-вывода установлен статус потока отличающийся от ios:: goodbit, дальнейшее выполнение операций по работе с потоком может стать невозможным. Для попытки продолжения работы с потоком в этом случае следует воспользоваться потоковой функцией clear (). Эта функция очищает статус потока ввода-вывода и устанавливает флаг статуса ios:: goodbit.

Функция потока ввода peek () позволяет прочитать из потока очередной символ, не удаляя его из потока.

Функция putback (char c) возвращает в поток ввода символ c.

При выводе данных на некоторое устройство эти данные сначала накапливаются в буфере вывода и, когда этот буфер заполняется, сбрасываются на устройство (например, запись на диск). Этот прием называется буферизацией данных. Он позволяет существенно увеличить быстродействие операций вывода данных. Однако в некоторых ситуациях требуется осуществлять запись данных на устройство, не дожидаясь заполнения буфера. Для этого можно использовать функцию потока вывода flush ().

Пример 1. Для выполнения этой программы скопируйте ее текст в новый проект.

//////////////////////////////////

// Эта программа предназначена для иллюстрации работы с файлами в двоичном режиме.

// Обеспечивает:

// 1. Ввод и добавление в файл Persons.dat сведений о людях.

// 2. Чтение данных из файла Persons.dat и вывод их на экран.

// Данные о людях (персонах) включают в себя фамилию, имя и год рождения,

// оформленные в виде структуры t_Person.

// Различного рода запросы, требующие ответа "да" или "нет", реализуются

// с помощью функции MessageBox() из заголовочного файла <windows.h>.

// Эта функция возвращает целочисленные значения 6 и 7, означающие "да" или "нет"

// соответственно.

// Для очистки экрана в программе используется функция system("cls"), которая

// выполняет команду операционной системы cls - очистка экрана.

// Для русификации консольного ввода-вывода используются потоки консольного

// ввода-вывода wcin и wcout, а вместо типа char двухбайтные символы типа wchar_t

// и кодовая страница.866, устанавливаемая в главной функции с помощью

// функции setlocale(LC_ALL, ".866")

////////////////////////////////////

#include "stdafx.h"

#include <iostream> // Для работы со стандартными потоками ввода-вывода

#include <fstream> // Для работы с файлами

#include <windows.h> // Для использования функции MessageBox()

#include <iomanip> // Для использования функции setw()

using namespace std;

bool FileExists (char *FileName)

// Возвращает true, если файл FileName существует

{

ifstream File (FileName); // Открываем файл для чтения

bool Fl = (bool)File; // Фиксируем результат открытия файла в переменной Fl

File.close(); // Закрываем файл

return Fl; // Возвращаем значение true, если файл существует

}

struct t_Person // Тип данных для "персоны"

{

wchar_t Fam[20]; // Фамилия

wchar_t Name[20]; // Имя

int Year; // Год рождения

};

void ReadConPerson(t_Person &P)

// Ввод данных персоны с клавиатуры

{

int W = 17; // Ширина поля вывода для подсказки

wcout << setw(W) << L"Фамилия: "; // Выводим подсказку для фамилии

wcin >> P.Fam; // Вводим фамилию

wcout << setw(W) << L"Имя: "; // Выводим подсказку для имени

wcin >> P.Name; // Вводим имя

wcout << setw(W) << L"Год рождения: "; // Выводим подсказку для года рождения

wcin >> P.Year; // Вводим год рождения

}

void WriteConPerson(t_Person P)

// Вывод данных персоны на экран

{

int W = 17; // Ширина поля вывода для подсказки

wcout << setw(W) << L"Фамилия: " << P.Fam << endl; // Выводим фамилию

wcout << setw(W) << L"Имя: " << P.Name << endl; // Выводим имя

wcout << setw(W) << L"Год рождения: " << P.Year << endl; // Выводим год рождения

}

void WriteFile(char FN[])

// Чтение данных с клавиатуры и их запись в файл с именем FN

{

t_Person P; // Переменная для персоны

fstream File(FN, ios::out | ios::binary | ios::app); // Открываем файл для добавления данных в двоичном режиме

do

// Цикл до тех пор, пока мы не откажемся от ввода данных

{

system("cls"); // Чистим экран

ReadConPerson(P); // Вводим данные с клавиатуры в переменную P

File.write((char *) &P, sizeof(P)); // Записываем данные из переменной Р в файл

}

while (MessageBox(NULL, L"Продолжим ввод?", L"Запрос", MB_YESNO | MB_ICONQUESTION | MB_TOPMOST | MB_DEFBUTTON1)!= 7);

File.close(); // Закрываем файл

}

void ReadFile(char FN[])

// Чтение данных из файла с именем FN и вывод их на экран

{

t_Person P; // Переменная для персоны

fstream File(FN, ios::in | ios::binary); // Открываем файл для чтения данных в двоичном режиме

if (!File) // Если файл не удалось открыть, выходим из функции

return;

do

// Цикл до тех пор, пока мы не откажемся от вывода данных

{

int Count = 1; // Счетчик выведенных персон

File.clear(); // Очищаем статус состояния потока ввода

File.seekg(0); // Устанавливаем указатель чтения файла в начало файла

do

// Цикл до тех пор, пока не закончился файл или мы не откажемся от вывода данных

{

File.read((char *) &P, sizeof(P)); // Читаем из файла в переменную Р данные об очередной персоне

if (!File.eof()) // Если не достигнут конец файла, то выводим на экран данные о персоне

{

system("cls"); // Очищаем экран

wcout << L"Персона " << Count++ << ":\n"; // Выводим на экран подсказку с номером Count персоны и увеличиваем

// значение Count на единицу

wcout << "----------\n"; // Подчеркиваем подсказку

WriteConPerson(P); // Выводим на экран значение переменной Р с данными о персоне

}

}

while (!File.eof() &&

(MessageBox(NULL, L"Продолжим?", L"Запрос", MB_YESNO | MB_ICONQUESTION | MB_TOPMOST | MB_DEFBUTTON1)!= 7));

}

while (MessageBox(NULL, L"Вывод закончен.\nНачнем сначала?", L"Запрос", MB_YESNO | MB_ICONQUESTION | MB_TOPMOST | MB_DEFBUTTON2)!= 7);

File.close(); // Закрываем файл

}

int _tmain(int argc, _TCHAR* argv[])

{

setlocale (LC_ALL, ".866"); // Устанавливаем русифицированную кодовую страницу для консоли

char FN[] = "Persons.dat"; // Имя файла для данных персон

do

// Цикл до тех пор, пока мы не откажемся от продолжения работы

{

bool Ok = FileExists(FN); // В переменной Ок фиксируем наличие (отсутствие) файла с именем FN

if ((!Ok) || (Ok &&

(MessageBox(NULL, L"Будем добавлять данные в файл?", L"Запрос", MB_YESNO | MB_ICONQUESTION | MB_TOPMOST | MB_DEFBUTTON2) == 6)))

// Если файл отсутствует или он имеется, и мы хотим добавить в него данные, то вводим данные с клавиатуры и записываем их в файл

WriteFile(FN); // Чтение данных с клавиатуры и их запись в файл с именем FN

if (MessageBox(NULL, L"Будем читать данные из файла?", L"Запрос", MB_YESNO | MB_ICONQUESTION | MB_TOPMOST | MB_DEFBUTTON1) == 6)

// Если мы хотим прочитать данные из файла, то читаем их из файла и выводим на экран

ReadFile(FN); // Чтение данных из файла с именем FN и вывод их на экран

}

while (MessageBox(NULL, L"Закончить работу?", L"Запрос", MB_YESNO | MB_ICONSTOP | MB_TOPMOST | MB_DEFBUTTON2)!= 6);

return 0;

}


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: