Теперь покажем, как использовать двунаправленный поток (листинг 14.17).
Листинг 14.17. Применение двунаправленного строкового потока
{ string names[4] = {"Peter", "Mike", "Shea", "Jerry"}; string temp[4]; string name; int age; long salary;
stringstream strm; // двунаправленный поток
srand( (unsigned)time(NULL)); // инициализация датчика случайных чисел /* создание данных name, age и salary */ for (int loop=0; loop < 4; ++loop) strm<<names[loop]<<' '<<rand()%10+20<<' '<<rand()%5000+27500L<< endl;
/* вывод шапки */
cout << setw(4) << "#" << " | "
<< left << setw(20) << "Name" << м | "
<< right << setw(5) << "Age" << " | "
<< right << setw(15) << "Salary" << endl;
cout << " \n";
strm.seekg(6); // перевод позиции чтения/записи в начало потока
for (loop=0; loop < 4; ++1оор)
{ strm >> name >> age >> salary; // ввод name, age и salary cout << right << setw(4) << (loop + 1) << " | " << left << setw(20) << name << " | " << right << setw(5) << age << " | "
<< setw(15) << salary << endl;
}
}
Эта программа сначала пишет в поток strm. Потом из того же потока выполняется считывание и вывод на экран.
Перед считыванием устанавливается позиция чтения методом seekg (см. п. п. 27.6.1.3 в [1]). В объектно-ориентированной библиотеке позиционирование можно выполнять и для строковых, и для файловых потоков — этого нельзя делать только для стандартных потоков. Мы рассмотрим методы позиционирования далее.
Входной строковый поток можно использовать, чтобы реализовать считывание чисел из поля фиксированной длины. Не будем писать манипулятор с аргументами, а напишем простой шаблон функции (листинг 14.18).
Листинг 14.18. Ввод из поля фиксированной длины
template <class Т>
void fixedread(istream &in, T &t)
{ if (in.width() > 0) // ширина поля установлена
{ string field;
in >> field; // ввод по ширине или до пробела
istringstream strm(field); // входной строковый поток
if (!(strm >> t) // ввод из строкового потока
in.setstate(ios::failbit); // ошибки ввода
}
else // ширина поля по умолчанию
in >> t; // ввод в переменную
}
Если ширина поля ввода установлена (то есть не равна нулю), то объявляется строка для ввода и ввод выполняется в нее. Чтение выполняется либо до пробела, либо до заявленного количества символов. Затем этой строкой инициализируется строковый поток. Обратите внимание на то, что ввод из строкового потока проверяется на корректность и в случае ошибки устанавливается флаг f ai 1 bi t для входного потока-параметра.
Использовать эту функцию можно так:
int к = 0; cin.width(3); fixedread(cin, к);
Если мы последовательно нажмем клавиши 1, 2, 3, 4, то в переменную к попадет значение 123, а при нажатии, например, клавиш 5,6, -пробел, 4,5,6,7 — значение 56.
|