While (i_File)

Запись и чтение данных в двоичном режиме

Запись и чтение данных в текстовых файлах

Запись и чтение данных в текстовых файлах ничем не отличается от способов ввода-вывода данных с помощью потоков cin и cout. Методы форматирования вывода и вводы данных остаются такими же (флаги форматирования, манипуляторы, функции потоков).

Необходимо помнить, что при использовании операции >> для чтения данных из текстовых файлов, процесс чтения останавливается при достижении пробельного символа (так же как и в потоках cin и cout). Поэтому для чтения строки текста, содержащей несколько слов, необходимо, как и раньше, использовать, например, функцию getline ().

Для работы с файлом в двоичном режиме его необходимо открыть с флагом ios:: binary.

Чтение и запись двоичных данных в этом режиме можно осуществлять двумя способами:

· по одному байту – функции файловых потоков get () и put ();

· блокам определенной длины - функции файловых потоков read () и write ().

Один из вариантов прототипов функций get () и put () (чаще всего используемый) выглядит так:

ifstream & get (char & ch);

ofstream & put (char ch);

Функция get () берет один символ из потока ввода, помещает его в символьный параметр ch и возвращает ссылку на поток ввода. Когда достигается конец файла, значение ссылки на поток становится равным 0.

Функция put () помещает символ ch в поток вывода и возвращает ссылку на поток вывода.

В следующей программе с помощью этих функций осуществляется запись в файл массива А из 5 целых чисел, чтение из файла этих данных в массив В и вывод массива В на экран:

int main ()

{

setlocale (0, "");

// Запись массива А в_файл "E:\test.dat"

ofstream o_File; // Создали поток вывода для записи данных в файл

o_File.open ("E:\\test.dat", ios::binary); // Открыли файл

if (! o_File.is_open()) // Проверили, удалось ли открыть файл

{

cout << "Открыть файл не удалось! \n";

return 0;

}

// Записываем данные из массива А в файл

int A[5] = {1, 2, 3, 4, 5};

char *ch = (char *) A; // ch – ссылка на массив А, как на массив символов (байт)

for (int I = 0; I < sizeof(A); ++ I)

o_File.put(ch[I]);

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

// Чтение данных из_файла "E:\test.dat" в массив В;

ifstream i_File; // Создали поток ввода для чтения данных из файла

i_File.open ("E:\\test.dat", ios::binary); // Открыли файл

if (! i_File.is_open()) // Проверили, удалось ли открыть файл

{

cout << "Открыть файл не удалось! \n";

return 0;

}

// Читаем данные из файла в массив B

int B[5];

ch = (char *) B; // ch – ссылка на массив В, как на массив символов (байт)

int I = 0;

i_File.get(ch[I++]);

// Предыдущий цикл можно записать короче, например, так:

// while (i_File.get(*ch++);

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

// Выводим массив В на экран

for (I = 0; I < 5; ++ I)

cout << B[I] << " ";

cout << endl;

system("pause");

return 0;

}

А вот как выглядит та же программа при использовании блочных функций чтения и записи (read () и write ()) в двоичном режиме:

int main ()

{

setlocale (0, "");

// Запись массива А в_файл "E:\test.dat"

ofstream o_File; // Создали поток вывода для записи данных в файл

o_File.open ("E:\\test.dat", ios::binary); // Открыли файл

if (! o_File.is_open()) // Проверили, удалось ли открыть файл

{

cout << "Открыть файл не удалось! \n";

return 0;

}

int A[5] = {1, 2, 3, 4, 5};

o_File.write ((char *) A, sizeof (A)); // Записываем данные из массива А в файл

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

// Чтение данных из_файла "E:\test.dat" в массив В;

ifstream i_File; // Создали поток ввода для чтения данных из файла

i_File.open ("E:\\test.dat", ios::binary); // Открыли файл

if (! i_File.is_open()) // Проверили, удалось ли открыть файл

{

cout << "Открыть файл не удалось! \n";

return 0;

}

int B[5];

i_File.read ((char *) B, sizeof (B)); // Читаем данные из файла в массив B

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

// Выводим массив В на экран

for (int I = 0; I < 5; ++ I)

cout << B[I] << " ";

cout << endl;

system("pause");

return 0;

}

Функции read () и write () имеют следующие прототипы:

ifstream & read (char * buf, streamsize n);

ofstream & write (const char * buf, streamsize n);

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

Функция write () обеспечивает запись из буфера, адрес которого указан в первом параметре функции, n символов данных в поток вывода и возвращает ссылку на поток.

Функция read () обеспечивает запись из потока ввода n символов данных в память по адресу, указанному в первом параметре buf. При достижении конца файла функция возвращает ссылку на поток, равную 0, а фактическое количество взятых из потока символов может быть меньше, чем значение n второго параметра (буфер заполнен не полностью). Фактическое количество считанных из потока ввода символов после выполнения последней операции чтения можно определить с помощью функции потока ввода gcount(). Следующий пример иллюстрирует использование функций блочного чтения и записи данных из произвольного файла.

void FileToScr (char * FileName)

{

fstream File (FileName, ios::in | ios::binary);

if (!File) // Проверили удалось ли открыть файл

{

cout << "Открыть файл не удалось! \n";

return;

}

char Buf [1024];


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



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