В потоковых классах наряду с операторами извлечения из потока и включения в поток определены также методы для неформатированного чтения (неформатированного ввода) и записи в поток (неформатированного вывода). При этом преобразование данных не выполняется.
Функции чтения, определенные в классе istream:
· gcout – возвращает количество символов, считанных с помощью последней функции неформатированного ввода.
· get() – возвращает код извлеченного из потока символа или EOF.
· get(c) – возвращает ссылку на поток, из которого выполнялось чтение, и записывает извлеченный символ в c.
· get (buf, num, lim=) – считывает num-1 символов или пока не встретится символ lim и копирует их в символьную строку buf, вместо символа lim в строку записывается признак конца строки. Символ lim остается в потоке. Возвращает ссылку на текущий поток.
· getline(buf, num, lim =) – аналогична функции get(...) копирует в строку и символ lim.
· ignore(num = 1, lim = EOF) – считывает и пропускает символы до тех пор, пока не будет прочитано num символов или не встретится разделитель, заданный параметром lim. Возвращает ссылку на текущий поток.
· peek() – возвращает следующий символ без удаления его из потока или EOF, если достигнут конец файла
· putback(c) – помещает в поток символ с, который становится текущим при извлечении его из потока.
· read(buf, num) – считывает num символов, или все символы до конца файла, если их меньше num соответственно в символьный массив buf и возвращает ссылку на текущий поток.
· readsome(buf, num) – считывает num символов или все символы, если их меньше num в массив buf и возвращает количество символов.
· seekg (pos) – устанавливает текущую позицию чтения в значение pos.
· seekq (offs, org) – перемещает текущую позицию чтения на offs байтов, считая от одной из трех позиций, определенных вторым параметром (ios::cur – от текущей позиции, ios::end – от конца файла).
· tellq() – возвращает текущую позицию чтения потока.
· unget() – помещает последний прочитанный символ в поток и возвращает ссылку на текущий поток.
В классе ostream определены аналогичные функции для неформатированного вывода.
· flush(c) – описывает содержание потока выводя на физическое устройство.
· put(c) – выводит в поток символ с и возвращает ссылку на поток.
· seek(pos) – устанавливает позицию записи в значение pos.
· seek(offs, org) – перемещает текущую позицию записи на offs байтов, считая от одной из трех позиций, определенных вторым параметром (ios::beg, ios::cur, ios::end).
· tellq() – возвращает текущую позицию записи потока.
· write(buf, num) – записывает в поток num символов из массива buf и возвращает ссылку на поток.
Пример 1
Пример программы, считывающей строки из массива buf и возвращающей ссылку на поток:
#include<iostream.h>
Int main()
{
const int n=20, len = 100;
char str[len][n] int i =0;
while(cin, getline(str[i], len,)&&i<n)
{
...
i++;
}
return 0;
}
Пример 2
Пример программы, записывающей в файл число с плавающей точкой в строку символов. Программа осуществляет считывание из файла и вывод на экран.
#include<fstream.h>
#include<string.h>
Int main()
{
//запись в файл
ofstream out(“text”);
if(!out)
{
cout<<”cannot open file test for writing” << endl;
return 1;
}
double num = 100.45;
char str[]=” this is a test”;
out.write(reinterpret_cast<char *>(num), sizeof(double));
out.write (str, strlen(str));
out.close();
//чтение из файла
ifstream in(“test”, ios::n| ios::nocreate);
if(!in)
{
cout << “cannot open file test for reading” << endl;
return 1;
}
double check_num;
char check_str[60];
in.read(reinterpret_cast<char *> (& check_num), sizeof(double));
in.read(check_str, 60);
int lstr = in.ycout(); // количество прочитанных символов
check_str[lstr]=0; // занести нуль-символ в конец строки
cout << check_num << ‘ ‘ << check_str << endl;
in.close();
return 0;
}
Приведение типа reinterpret_cast <char *> при вызове функций write и read необходимо в тех случаях, когда параметр не является символьным массивом.
Пример 3
Пример программы, в которой формируется файл test, в который выводятся три строки:
#include<fstream.h>
#include<string.h>
Int main()
{
// запись в файл
ofstream out(“test”);
if(!out)
{
cout<<”cannot open file test for writing” << endl;
return 1;
}
char *str[] = {“line 1”, “line 2”, “line 3”};
for(int i=0; i<3; ++i)
{
out.write(str[i], strlen(str[i]));
out.put();
}
out.close();
//чтение файла
ifstream in(“test”, ios::in| ios::nocreate);
if(!n)
{
cout << “cannot open file test for reading” << endl;
return 1;
}
char check_str[3][60];
for(i=0; i<3; ++i)
{
in.get(check.str[], 60);
in.get();
}
//контрольный вывод
for(i=0; i<3; ++i)
cout << check_str[i] << endl;
in.close();
return 0;
}
После выполнения функции символ-разделитель остается во входном потоке, следовательно, необходим вызов функции get для пропуска одного символа. Альтернативный способ – использование функции getline, которая извлекает символ-разделитель из потока.
Классы с самоадресацией
Классы с самоадресацией - классы, которые содержат элемент-указатель, который указывает на объект того же типа класса:
Пример 1
Class Node
{
public:
Node(int);
void setdata(int);
int getdata() const;
void setnextptr(const Node *);
const Node * getnextptr() const;
private:
int data;
Node * nextptr;
};
Данное описание определяет тип класса Node – он имеет два закрытых элемента данных: целый элемент data и указатель nextptr, который указывает на объект типа Node, т.е. объект того же тип. Такие классы называются классами с самоадресацией. В них элемент nextptr используется как связывающий, т.е. nextptr может быть использован для связи объекта типа Node с объектом того же типа. У типа Node также имеется пять функций-элементов: конструктор, который принимает данные целого типа, для инициализации данных поля data; функция для установки значения data; функция getdata, возвращающая значение data: функция setnextptr для установки значения указателя nextptr, а также функция getnextptr, которая возвращает значение указателя nextptr. Объекты классов с самоадресацией могут связываться друг с другом, формируя абстрактные структуры данных: связные списки, очереди, стеки, деревья.
На рисунке показано два объекта класса с самоадресацией, связанные вместе для создания структуры «список». Обратный слеш отображает нулевой указатель, помещенный в элемент связи второго объекта, чтобы было ясно, что эта связь не указывает на какой-либо другой объект.
Типичная ошибка: указатель связи в последнем узле не установлен на ноль.
Глава 13. Взаимосвязь и различия C и C++