Конструкторы файловых потоков

Для каждого из трех классов файловых потоков предусмотрено по четыре перегруженных конструктора. Рассмотрим два из них, применяемых наиболее часто. Это, в первую очередь, три пустых конструктора:

ifstream() ofstream() fstream()

{ { {

} } }

Они конструируют объекты, не открывая файла. Например, ifstream ifs; ofstream ofs; fstream f1,f2;

Три вторых конструктора позволяют конструировать объект, открыть файл и прикрепить объект к файлу. Их заголовки имеют вид:

ifstream(const char*name,int omode=ios::in,int prot=filebuf::openprot);

ofstream(const char*name,int omode=ios::out,int prot=filebuf::openprot);

fstream (const char*name,int omode, int prot=filebuf::openprot);

24.3 Открытие файла

Чтобы открыть файл, можно использовать конструкторы ifstream, ofstream или fstream. Автоматически вызываются вторые конструкторы. Для ifstream и ofstream обязательными являются лишь имена файлов. Остальные два параметра берутся по умолчанию. При вызове fstream необходимо обязательно передать первые два параметра: имя файла и режим его работы.

Примеры.

ifstream ifs1(“ish.dan”);

ofstream of1(“rezult.dan”);

ofstream of2(“rezult2.txt”,ios::app);

Файл rezult2.txt используется для дозаписи в конец файла (append).

fstream fil1(“file1.txt”,ios::in);

file1.txt – для чтения.

fstream fil2(“file2.dan”,ios::out);

fstream fil3(“file3.dan”,ios::app);

Файлы file2.dan и file3.dan созданы соответственно для записи и для дозаписи в конец файла.

Открыть файл можно также с помощью функции –члена open() класса ios. Ее прототип имеет вид:

filebuf*open(const char*name,int mode, int prot=filebuf::openprot);

При ее вызове обязательными являются только первые два параметра: имя файла и режим его работы (доступа). Режимы доступа задаются перечисляемыми битовыми масками в классе ios.

еnum open_mode

{

in=0x01://open for reading

out=0x02://open for writing

ate=0x04://seek to end of file upon original//open

app=0x08://append mode

trunc=0x10://trancate file if already exist

nocreate=0x20:// open fails if file doesn’t exist

noreplace=0x40:// open fails if file already exists

binary=0x80:// binary file

};

Примеры.

Предположим, с помощью пустого конструктора были созданы объекты:

fstream fin, fout;

fin.open(“ish.dan”, ios::in);

fout.open(“rez.dan”, ios::out);

Эти два файловых объекта открыты соответственно для чтения и для записи. Можно указывать несколько режимов доступа через вертикальную линию. Например:

fout.open(“rez.dan”, ios::out|ios::ate);

Закрытие файла

В классах файловых потоков имеется метод close, который опорожняет поток и закрывает закрепленный за потоком файл. Примеры:

fin.close ( );

fout.close ( );

Предполагается, что деструктор файлового объекта (или его базового класса) автоматически закрывает файл.

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

Пример 1 Табулирование функции. Исходные данные размещаются в файле ish.dan, а результаты будут заноситься в файл rez.dan.

# include < iostream. h >

# include < fstream. h >

# include < math. h >

# include < stdlib. h >

void main ( )

{

ifstream fin (“ist. dan”);

if (fin)

{

cout << “не открылся файл ish. dan” <<’\ n ‘;

exit (1);

}

ofstream fout (“rez. dan”);

double x, y, xn, dx, xk;

fin >>xn>>dx>>xk;

fout << “xn=” <<xn<<” dx=” <<dx<<“ xk = “<<xk<<’ \ n ‘;

for (x = xn; x <= xk; x += dx)

{

y = exp ( -x );

fout << “ x = “ <<x<< ” y = “<< y << ‘ \ n’;

}

fin. close ( );

fout. close ( );

}

Пример 2 Постановка задачи.

Описать класс «матрица». Предусмотреть функцию-член для ввода элементов матрицы из выходного файла, дружественную функцию для их сложения и член-функцию для занесения результирующей матрицы в файл результатов. Количество строк и столбцов считать заведомо известными.

# include < iostream. h >

# include < fstream. h >

# include < stdlib. h >

# define N 2

# define M 3

class matr

{

float x [ N ] [ M ];

public:

void vvod (char * S);

void vivod (char * S);

friend matr operator + (matr & a, matr & b);

};

void matr :: vvod (char * S)

{

ifstream ifs (S);

if (ifs)

{

cout << “Не открылся файл” << S << ‘ \ n ‘;

exit (1);

}

for ( int i = Ø; i < N; i + +)

for ( int j = Ø; j < M; j + +)

ifs >> x [ i ][ j ];

}

void matr :: vivod ( char * S)

{

ofstream ofs ( S );

for (int i = Ø; i < N; i ++)

for (int j = Ø; j < M; j ++)

ofs <<x [ i ][ j ];

}

matr operator + ( matr & a, matr & b)

{

matr z;

for (int i = Ø; i < N; i ++)

for (int j = Ø; j < M; j ++)

z. x [ i ] [ j ] = a. x [ i ] [ j ] = b. x [ i ] [ j ] ;

return z;

}

void main ( )

{

matr v, w, q

v. vvod (“v. dan”);

w. vvod (w. dan”);

q = v + w;

q. vivod (“q. dan”);

}

Матрицы v и w записаны соответственно в файлах v.dan и w.dan. Результирующая матрица q заносится в файлq.dan.

24.5 Перегрузка операций сдвига для файлового ввода/вывода

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

friend ifstream & operator >> (ifstream & ifs, имя класса & имя объекта);

friend ofstream & operator << (ofstream & ofs, имя класса & имя объекта);

Пример. Условия задачи такие же, как и в предыдущем примере, но складываемые матрицы находятся в одном файле v hod. dan.

Пусть конкретно находится серия матриц v [ 2 ] [ 3 ] и w [ 2 ] [ 3 ]. Их элементы последовательно записаны в файле v hod. dan. Например, в файле v hod. dan имеются следующие числа:

1 2 3

4 5 6

-1 -2 -3

-4 -5 -6

Первые две строки – элементы матрицы v, а вторые – матрицы w.

# include < iostream. h >

# include < fstream. h >

# include < stdlib.h >

# define N 2

# define M 3

class matr

{

float x [ N ] [ M ];

friend ifstream & operator >> (ifstream & ifs, matr & x);

friend ofstream & operator << (ofstream & ofs, matr & a);

friend matr operator + (matr & a, matr & b);

};

ifstream & operator >> (instream & ifs, matr & x)

{

for (int I = Ø; I < N; I ++)

for (int j = Ø; j < M; j ++)

ifs >>x. x [ I ] [ j ]; / * Допускается совпадение символических имен элементов данных и параметров * /.

return ifs; //Не забывать!

}

ofstream & operator << (ofstream & ofs, matr & a)

{

for (int I = Ø; I < N; I ++)

for (int j = Ø; j < M; j ++)

ofs << a. x [ I ] [ j ];

return ofs;

}

matr operator + (matr & a, matr & b)

{

matr v;

for (int I = Ø; I < N; I ++)

for (int j = Ø; j < M; j ++)

v. x [ I ] [ j ] = a. x [ I ] [ j ] + b. x [ I ] [ j ];

return v;

}

void main ( )

{

matr w, v;

ifstream fvh (“v hod. dan”);

fvh >> v >> w; // * Дважды вызывается оператор >>. Первой вводится матрица v, а за ней w */

matr q;

q = v + w; //вызывается оператор + ( ).

ofstream viv (“q. dan”);

viv << q; //Вывод q в файл q.dan.

//Вызывается оператор << ( ).

}

Лекция 25

Форматирование данных

Библиотека потоков С + + предусматривает три способа управления форматом выходных данных: вызов форматирующих функций – элементов, использование флагов и применение манипуляторов.

Наши рекомендации