Работа
с потоками
Шаблон класса
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