Работа с потоками
Шаблон класса if stream позволяет работать с файловыми потоками и производить ввод объектов произвольного типа. Удобно вводить объекты прямо в контейнер. Специальный итератор (istream_iterator) помогает в этом случае воспользоваться алгоритмами (например, сору). При достижении конца потока (end of stream) итератор принимает специальное значение, которое служит барьером выхода за пределы потока (past-the-end iterator).
В примере, приведенном ниже, используется еще один тип итератора (back_insert_iterator). Он является адаптером, позволяющим вставлять элементы в конец последовательности. Если использовать прямой inserter, то при чтении из файла последовательность будет реверсирована (перевернута). Позиционирование в потоке осуществляется с помощью метода seekg, техника использования которого также демонстрируется в примере:
void main ()
{
//========== Вектор строк
vector<string> v;
v.push_back("Something in the way ");
v.push_back("it works distracts me ");
v.push_back("like no other matter");
pr(v,"Before writing to file");
//========== Запрашиваем имя файла
cout << "\nEnter File Name: ";
string fn, text; cin >> fn;
//========== Приписываем расширение
int pos = fn.rfind(".");
if (pos > 0)
fn.erase(pos);
fn += ".txt";
//========== Создаем и открываем поток
ofstream os(fn.c_str());
//========== Определяем входной и выходной потоки
typedef istream_iterator<string, char,
char_traits<char> > Strln;
typedef ostream_iterator<string, char,
char_traits<char> > StrOut;
//========== Копируем контейнер в выходной поток
copy (v.begin(), v.end(), StrOut(os,"\n"));
os.close();
//========== Открываем файл для чтения
if stream is(fn.c_str());
//========= Пропуск 17 символов
is.seekg(17);
is >> text;
cout << "\n\nStream Positioning:\n\n" << "17 bytes:\t\t" << text << endl;
//========== Устанавливаем в начало потока
is.seekg(0, ios_base::beg);
is >> text;
cout << "0 bytes:\t\t" << text << endl;
//========== Сдвигаем на 8 символов от конца
is.seekg(-8, ios_base::end);
is >> text;
cout << "-8 bytes from end:\t" << text << "\n\n";
//========== Устанавливаем в начало потока
is.seekg(0, ios_base::beg);
v.clear ();
//========== Копируем в контейнер
copy(Strln(is),Strln(),back_inserter(v));
pr(v,"After reading from file");
cout<<"\n\n"; }
Программа производит следующий выход:
Before writing to file # Sequence: 1. Something in the way 2 .it works distracts me 3 .like no other matter Enter File Name: test Stream Positioning: 17 bytes: way 0 bytes: Something -8 bytes from end: matter After reading from file # Sequence: 1. Something 2 .in 3 .the 4 .way 5 .it 6 .works 7 .distracts 8 .me 9 .like 10 .no 11 .other 12 .matter
