Сделай Сам Свою Работу на 5

Операции помещения и извлечения





 

Библиотека потоков С++ предусматривает два основных класса для ввода и вывода: соответственно istream и ostream. Класс ostream использует для вывода операцию левого сдвига(<<). Если эта операция применяется к объектам-потокам, ее называют операцией помещения (в поток). Следующий пример выводит приветствие, применяя операцию помещения к предопределенному объекту cout.

 

#include<iostream.h>

void main(0

{

cout<<”Всем привет!” <<’\n’;

}

 

После приветствия стоит символ перевода на новую строку ‘\n’.

Класс istream использует для ввода операцию правого сдвига (>>). В таком контексте ее часто называют операцией извлечения (из потока). Следующий пример применяет операцию извлечения к предопределенному объекту cin.

 

#include<iostream.h>

void main(0

{

char name [20]];

cout<<”Введите имя”;

cin >>name;

}

 

Классы istream и ostream перегружают соответственно операции извлечения и помещения для всех встроенных типов. Такая перегрузка позволяет использовать единообразный синтаксис для ввода/вывода символов, строк, целых и вещественных типов.

Кроме того, перегруженные операции << и >> возвращают ссылку на объект (return*this) соответствующего типа. Это позволяет последовательно соединять несколько операций, т.е. реализовать сцепление вызовов операций ввода/вывода.



Например:

cout<<”Введите а,в,с” <<’\n’;

cin >>а>>в>>с;

cout<<”Вы ввели: а=”<<a<<” в=”<<в<<” c=”<<c<<’\n’;

В этом фрагменте программы приведены сцепленные операции ввода и вывода.

В следующей программе приведены примеры перегруженных операций для встроенных типов.

 

#include<iostream.h>

#include<iomanip.h>

void main(0

{

int k;

cout<<”Введите k=” <<’\n’;

cin >>k;

long m;

cout<<”Введите m=” <<’\n’;

cin >>m;

float x;

cout<<”Введите x=” <<’\n’;

cin >>x;

double y;

cout<<”Введите y=” <<’\n’;

cin >>y;

char nch;

cout<<”Введите символ nch =” <<endl;/*endl – т.н. манипулятор. Он помещает в поток символ новой строки (\n) и вызывает манипулятор flush, который принудительно записывает все данные на соответствующие физические устройства. Поэтому endl рекомендуется ставить перед вводом символа и строки */

cin >> nch;

char name [15];

cout<<”Введите name =” <<endl;



cin >> name;

cout<<”Вы ввели: k=”<<k<<” m=”<<m<<” x=”<<x<< y=”<<y<< nch=”<<nch<< name =”<< name <<’\n’;

}

 

 

Расширение потоков для типов, определяемых пользователем

 

 

Можно легко расширить библиотеку, чтобы приспособить операции помещения/извлечения к собственным типам данных. Для этого следует определить две функции со следующими заголовками:

// Чтение данных из потока

istream& operator >> ( istream &is, имя_типа &имя_перем.);

// Запись данных в поток

оstream& operator << ( ostream &os, имя_типа &имя_перем.);

 

При использовании классов следует операции извлечения и помещения объявлять друзьями данного класса. Это обеспечивает операции доступа к элементам данных.

Пример расширения потоков для объектов class dog.

 

#include<iostream.h>

#include<iomanip.h>

class dog

{

char*poroda;

char*name;

int nomer;

friend istream &operator>>( istream &is, dog &x.);

friend оstream &operator<<( ostream &os, dog &x.);

};

istream &operator>>( istream &is, dog &x.);

{

poroda=new char[15];

name=new char[10];

cout<<”Введите породу” <<endl;

is>>x.poroda;

cout<<”Введите имя” <<endl;

is>>x.name;

cout<<”Введите номер” <<’\n’;

is>>x.nomer;

return is;//Обязательно!

}

оstream&operator<<( ostream&os, dog &x.);

{

os<<”Порода–” <<x.poroda<<” Имя–”<<x. name<<” Номер–”<<x. nomer<<’\n’;

return os;//Обязательно!

}

void main()

(

dog q;

cin>>q;

cout<<q;

}

 

Описан объект q класса dog. При его вводе вызывается дружественная функция operator>>(). В этой функции вместо формальных параметров (ссылок) x и is будут соответственно q и cin. Результат работы функции через return is присваивается предопределенному объекту класса istream cin. Аналогично выполняется дружественная функция operator<<().



 

Лекция 24

24.1 Файловый ввод/вывод с применением потоков С++

 

 

Библиотека С++ содержит три специализированные класса для файлового ввода/вывода. Это следующие классы:

ifstream – для операций с входным дисковым файлом;

ofstream– для операций с выходным дисковым файлом;

fstream – для входных и выходных операций с файлом.

Эти классы являются производными соответственно от istream, оstream и iostream. Таким образом, они наследуют все их функциональные особенности, в т.ч. перегруженные операции << и >> для встроенных типов.

 

 

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

 

 

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

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.

 

 








Не нашли, что искали? Воспользуйтесь поиском по сайту:



©2015 - 2024 stydopedia.ru Все материалы защищены законодательством РФ.