Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Потоки ввода-вывода.doc
Скачиваний:
0
Добавлен:
14.11.2019
Размер:
338.94 Кб
Скачать

Листинг 4. Примеры открытия файловых потоков

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

// Filemode.срр: Режимы открытия файлов.

//

#include <f stream .,h>

#include <string.h>

#pragma hdrstop

#include <condefs.h>

char *data[] = {"It's the first line of test data.",

"Second ,line.",

"Third line.",

"That's enough!"};

//

// Функция для распечатки содержимого файла. //

int Print(char *fn) {

char buf[80] ;

ifstream ifs(fn) ;

if (!ifs) {

cout <<fn<< " - Error reading file." << endl;

return -1;

} while (ifs) {

ifs.getline(buf, sizeof(buf)) ;

if (ifs)

cout << buf<< end1;

} return 0;

}

#pragma argsused

int main(int argc, char* argv[])

{

char name[]= "Newfile.txt";

fstream fs(name, ios::in);

if (fs) { // Файл уже существует. cout “ name “ " - File already exists." << endl;

} else { // Создать новый файл.

cout<< name<< " - Creating new file."<< endl;

fs.open(name, ios::out);

for (int i=0; i<3; i++) fs << data[i] << endl;

}

fs.close () ;

cout << end1;

//

// Файл либо уже существовал, либо мы его только что

// создали. Распечатаем его.

// Print(name);

cout << endl;

//

// Допишем строку в конец файла.

// fs.open(name, ios::app);

if (rs) {

fs M<< data[3]<< endl;

fs.close ();

} Print(name);

return 0;

}

Рис. 3 Результат работы программы Filemode

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

Бесформатный ввод-вывод

До сих пор речь у нас шла почти исключительно о вводе-выводе с использованием операций извлечения/передачи данных. Эти операции перегружены для всех встроенных типов и выполняют соответствующие преобразования из внутреннего представления данных в текстовое и из текстового во внутреннее (машинное).

Однако в библиотеке C++ имеется немало функций бесформатного ввода-вывода, которые часто применяют для чтения и записи двоичных (не-текстовых) файлов.

Двоичный режим ввода-вывода

Двоичный режим открытия файла (с установленным битом binary) означает, что никакой трансляции данных при передаче из файла в поток и обратно производиться не будет. Речь здесь идет не о форматных преобразованиях представления данных. При текстовом режиме (он принимается по умолчанию) при передаче данных между файлом и потоком производится замена пар символов CR/LF на единственный символ LF (' \n ') и наоборот. Это происходит до преобразований представления, которые выполняются операциями извлечения/передачи. Двоичный ввод-вывод означает всего-навсего, что такой замены происходить не будет; тем не менее двоичный режим необходим при работе с сырыми данными, т. е. данными в машинной форме без преобразования их в текстовый формат.

Чтобы открыть файл в двоичном режиме, нужно, как уже упоминалось, установить в параметре mode конструктора потока или функции open() бит ios::binary.

Чтение и запись сырых данных

Чтение сырых данных производится функцией read () класса istream:

istream &read(char *buf, long len);

Здесь buf — адрес буфера, в который будут читаться данные, а len — число символов, которые нужно прочитать.

Запись сырых данных производится функцией write () класса ostream. Она выглядит точно так же, как функция read () :

ostream &write(char *buf, long len);

Здесь buf — адрес буфера, в котором содержатся данные, а len — число символов, которые должны быть записаны в поток.

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

ostream os (...);

os.write(...).write (...).write(...) ;

Вот небольшой пример записи и чтения сырых данных:

#include <iostream.h>

#include <fstream.h>

int main(void) {

char name[] = "testfile.dat";

int i = 1234567;

double d = 2.718281828;

//

// Открытие выходного потока в двоичном режиме

//и запись тестовых данных.

//

ofstream ofs(name, ios::out | ios::binary);

if (ofs) {

ofs.write((char*)&i, sizeof(i)); // Целое.

ofs.write((char*)&d, sizeof(d)); // Вещественное.

ofs.write(name, sizeof(name)); // Строка. ofs.close ();

}

//

// Открытие входного потока в двоичном режиме.

// if stream ifs(name, ios::in | ios::binary) ;

i = 0; //

d = 0; // Уничтожить данные.

name[0] = '\0'; //

//

// Прочитать данные.

//

if (ifs) {

ifs.read((char*)&i, sizeof (i));

ifs.read((char*)&d, sizeof(d));

ifs.read(name, sizeof(name));

ofs.close () ;

} //

// Проверка - напечатать прочитанные данные. //

cout “ "Data read from file: i = " << i<< ", d = " << d

<< ", name = " << name << endl;

return 0;

}

Некоторые функции потоков

В классах istream и ostream есть ряд функций, которые позволяют выполнять над потоками разные полезные операции (в основном при бесформатном вводе-выводе). Здесь мы опишем наиболее часто употребляемые из них.