Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lucik_op.doc
Скачиваний:
2
Добавлен:
01.03.2025
Размер:
2.88 Mб
Скачать

Состояние потока

Потоки istream или ostream имеют связанное с ними состояние. В классе ios, базовом для классов istream и ostream, имеется несколько public функций, позволяющих проверять и устанавливать состояние потока:

inline int ios::bad() const { return state & badbit; }

inline int ios::eof() const { return state & eofbit; }

inline int ios::fail() const { return state & (badbit | failbit); }

inline int ios::good() const { return state == 0; }

Состояние потока фиксируется в элементах перечисления, объявленного в классе ios:

public:

enum io_state { goodbit = 0x00,

eofbit = 0x01,

failbit = 0x02,

badbit = 0x04 };

Кроме отмеченных выше функций в классе ios есть еще несколько функций, позволяющих прочитать (rdstate) и очистить (clear) состояние потока:

inline int ios::rdstate() const { return state; }

inline void ios::clear(int _i=0){ lock(); state = _i; unlock(); }

Так, если было установлено состояние ошибки, то попытка выполнить ввод/вывод будет игнорироваться до тех пор, пока не будет устранена причина ошибки и биты ошибки не будут сброшены функцией clear().

#include "iostream.h"

main()

{ int i, flags;

char c;

do{ cin >> i;

flags=cin.rdstate(); // чтение состояния потока cin

if(flags & ios::failbit)

{ cout << "error in stream"<< endl;

cin.clear(0); // сброс всех состояний потока

cin>>c; // удаление не int значения из потока

}

else cout << i<<endl;

} while(flags); // пока ошибка во входном потоке

return 0;

}

В приведенном примере функция cin.clear(0) выполняет сброс всех установленных бит ошибки. Если требуется сбросить, например, только badbit, то clear(ios::badbit). На примере ниже показано, что состояние потока может быть проанализировано также при работе с файлами.

#include "fstream.h"

#include "iostream.h"

main()

{ ifstream in("file");

int state;

char ss[10];

while(1)

{ state=in.rdstate(); // чтение состояния потока in (файла)

if (state) // ошибка в потоке

{ if(state&ios::badbit) cout<<"ошибка открытия файла"<<endl;

else if(state&ios::eofbit) cout<<"в файле больше нет данных"<<endl;

return 0;

}

else in >> ss;

}

}

Необходимо также отметить, что в классе ios выполнена перегрузка операции ! :

inline int ios::operator!() const { return state&(badbit|failbit); }

то есть операция ! возвращает ненулевое значение в случае установки одного из бит badbit или failbit, иначе нулевое значение, например:

if(!cin) cout << ”ошибка потока cin”<<endl; // проверка состояния

else cin>>i; // входного потока

Строковые потоки

Особой разновидностью потоков являются строковые потоки, представленные классом strstream:

class strstream : public iostream

{ public:

strstream();

strstream(char *s, streamsize n,

ios_base::openmode=ios_base::in | ios_base::out);

strstreambuf *rdbuf() const;

void freeze(bool frz=true);

char *str();

streamsize pcount() const;

};

Важное свойство класса strstream состоит в том, что в нем автоматически выделяется требуемый объем памяти для хранения строковых данных. Все операции со строковыми потоками происходят в памяти в специально выделенном для них буфере strstreambuf. Строковые потоки позволяют облегчить формирование данных в памяти. В примере демонстрируется ввод данных в буфер, копирование их в компоненту s класса string и их просмотр.

#include "strstrea.h"

class string

{ char s[80];

public:

string(char *S) {for(int i=0;s[i++]=*S++;);}

void see(){cout<<s<<endl;}

};

void fun(const char *s)

{ strstream st; // создание объекта st

st << s << ends; // вывод данных в поток (в буфер)

string obj(st.str()); // создание объекта класса string

st.rdbuf()->freeze(0); // освобождение памяти в буфере

obj.see(); // просмотр скопированной из буфера строки

}

main()

{ fun("1234");

}

Вначале создается объект st типа strstream. Далее при выводе переданной в функцию символьной строки в поток добавлен манипулятор ends, который соответствует добавлению ’\0’. Функция str() класса strstream обращается непосредственно к хранимой в буфере строке. Следует отметить, что при обращении к функии str() объект st перестает контролировать эту память и при уничтожении объекта память не освобождается. Для ее освобождения требуется вызвать функцию st.rdbuf()>freeze(0).

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

#include "strstrea.h"

void fun(const char *s,int n)

{ char *buf=new char[n]; // входной буфер

strstream st(buf,n,ios::in|ios::out); // связывание потока st и буфера byf

st << s << ends; // ввод информации в буфер

if(st.good()) cout << buf<<endl; // проверка состояния потока

else cerr<<"error"<<endl; // вывод сообщения об ошибке

}

main()

{ fun("123456789",5);

fun("123456789",15);

return 1;

}

В результате выполнения программы получим:

error

123456789

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]