Потоки ввода-вывода Иерархия потоковых классов ios_base cin cout ios istream istringstream ifstream ostream iostream fstream ofstream ostringstream stringstream Ввод >> – форматированный ввод до разделителя(’ ’ ’\t’ ’\n’ – определяется функцией isspace()) Ввод символов: char c=cin.get(); cin.get(c); char buf[10]; cin.get(buf,10); // Ввод max 9 символов до ’\n’ и дописывание завершающего 0 // Завершающий символ ’\n’ остается в потоке! cin.gcount(); // число символов, считанных последней get() Пример char buf1[10], buf2[10]; cin.get(buf1,10); // 123 Enter cin.get(buf2,10); // Ошибка: 2 get подряд. В buf2 – пустая строка // Надо: cin.get(buf1,10); cin.get(); cin.get(buf2,10); // OK cin.getline(buf1,10); // то же, что и get, но символ ’\n’ изымается из потока cin.read(buf,n) // неформатированный ввод n символов в буфер без превращения его в строку // Если считывается < n символов, то устанавливается флаг ios::failbit, а cin.gcount() возвращает количество считанных символов cin.peek(); // не удаляет символ из потока. Возвр. символ, кот. прочтется следующим. cin.ignore(int n=1); // пропуск n символов в потоке cin.ignore(n,’\n’); cin.putback(); // возврат символа в поток Пример istream& operator>>(istream& is, complex& a) { char c; double re,im; is>>c; if (c==’(’) { s>>re>>c; if (c==’,’) s>>im>>c; } else { is.putback(c); s>>re; } a=complex(re,im); return is; } Вывод cout.put(c); cout.write(buf,10); // неформатированный вывод Состояние потока ios.eof(); ios.bad(); // true при попытке выполнения некорректной операции ios.fail(); // true если операция завершилась неудачно ios.good(); Флаги ios::eofbit ios::badbit ios::failbit ios::goodbit int i; cin>>i; if (!cin) ... while (cin>>i) ... Последние две инструкции работают за счет наличия в ios операторов operator void*() const { return !(state&(badbit|failbit)); } int operator!() const { return state&(badbit|failbit); } После некорректного ввода необходимо очистить поток: ios::clear(iostate f=ios::goodbit); Только если поток в состоянии good(), следующий ввод может выполниться. Если поток не в состоянии good(), то при вводе ничего не происходит Манипуляторы cout<<манипулятор; Требуют нового стиля: #include <iostream> ... using namespace std; hex dec oct – действуют на весь последующий вывод left right – действуют на весь последующий вывод fixed scientific – действуют на весь последующий вывод endl skipws flush Манипуляторы с параметрами Требуют #include <iomanip> setprecision(n) действует на весь последующий вывод setw(n) действует на 1 последующий вывод Файловые потоки Требуют #include <fstream> ifstream from(”a.txt”); if (!from) {...} ofstream to(”b.txt”); if (!to) {...} while (from.get(ch)) to.put(ch); bool eof(); // редко ofstream to1(”b.txt”, ios_base::app); // открытие файла в режиме дозаписи fstream f(”all.txt”, ios_base::in | ios_base::out); // открытие файла на чтение и запись bool is_open(); open(<имя>, openmode); close(); // вызывается в деструкторе Для fstream: seekp(pos); // установка текущей позиции для чтения seekp(pos,ios_base::beg или ios_base::cur или ios_base::end); pos=tellp();// считывание текущей позиции для чтения seekg(pos); // установка текущей позиции для записи seekg(pos,ios_base::beg или ios_base::cur или ios_base::end); pos=tellg();// считывание текущей позиции для чтения Строковые потоки Требуют #include <sstream> ostringstream os; os<<...<<endl; cout<<os.str(); os.str(””); // очистка os.seekp(0); os<<ends; // очистка – второй вариант Бинарные файлы и неформатированный ввод-вывод Данные в бинарных файлах не имеют разделителей и рассматриваются как поток байтов double d; ofstream of(”a.dat”,ios_base::binary); of.write((char*)&d,sizeof(d)); ifstream if(”a.dat”,ios_base::binary); if.read((char*)&d,sizeof(d)); Перегрузка операторов << >> для бинарного ввода/вывода