►Подклассы strstream...285
Потоковые классы позволяют программисту разбивать входные данные на числа и массивы символов. Так называемые "строковые потоки" позволяют использовать операции, определённые для файлов в классах fstream, для строк в памяти. Соответствующие классы istringstream и ostringstream определены в заголовочном файле sstream.
«В старых версиях С++ эти классы назывались istrstream и ostrstream и были определены в заголовочном файле strstream.»
[Советы]
Строковые потоки используют ту же семантику, что и соответствующие базовые классы для файлов, как видно из приведённой далее демонстрационной программы.
/* StringStream — чтение и разбор содержимого файла */
#include <fstream>
#include <sstream>
#include <iostream>
using namespace std ;
/* parseAccountInfo — чтение переданного */
/* буфера как если бы */
/* это был файл. */
/* Формат: имя, счёт, баланс. */
/* При корректной работе */
/* возвращает true. */
bool parseString( char* pString ,
char* pName ,
int arraySize ,
long& accountNum ,
double& balance )
{
/* Связывает объект istringstream с входной строкой */
istringstream inp( pString ) ;
/* Чтение до разделяющей запятой */
inp.getline( pName , arraySize , ',' ) ;
// Номер счёта
inp >> accountNum ;
// и его баланс
inp >> balance ;
/* Возврат состояния ошибки */
return !inp.fail( ) ;
}
int main( int nNumberofArgs , char* pszArgs[ ] )
{
setlocale ( LC_ALL ,".1251" ) ; /* печать русских текстов */
/* Файловый поток */
ifstream* pFileStream = new ifstream( "Accounts.txt" ) ;
if ( !pFileStream -> good( ) )
{
cout << "Невозможно открыть Accounts.txt" << endl ;
return 0 ;
}
/* Считываем строку файла, разбираем и выводим результат */
_________________
285 стр. Глава 24. Использование потоков ввода-вывода
for ( ; ; )
{
/* Добавляем разделитель */
cout << "=================" << endl ;
/* Читаем в буфер */
char buffer[ 256 ] ;
pFileStream -> getline( buffer , 256 ) ;
if ( pFileStream -> fail( ) )
{
break ;
}
/* Разбираем ввод на поля */
char name[ 80 ] ;
long accountNum ;
double balance ;
bool result = parseString( buffer , name , 80 ,
accountNum , balance ) ;
/* Вывод результата */
cout << buffer << " " ;
if ( result == false )
{
cout << "Ошибка разбора строки " ;
continue ;
}
cout << "Имя = " << name << ","
<< "Счёт = " << accountNum << ", "
<< "Баланс = " << balance << endl ;
/* Выводим поля в другом порядке ( вставка ends гарантирует нуль-завершённость буфера ) */
ostringstream out ;
out << name << ", "
<< balance << " "
<< accountNum << ends ;
/* Вывод результата. Класс istringstream работает и с классом string, но пока что мы не будем использовать эту возможность */
string oString = out.str( ) ;
cout << oString << " " << endl ;
}
/* Пауза для того, чтобы посмотреть на результат работы программы */
system( "PAUSE" ) ; return 0 ;
}
Программа начинает работу с открытия файла Accounts.txt, содержащего информацию в формате
Имя, номер счёта, баланс,
В предположении, что файл открыт успешно, программа входит в цикл, считывающий файл построчно до его полного прочтения. Строки считываются при помощи функции-члена getline( ), который читает их до символа новой строки. Затем считанная строка передаётся функции parseString( ).
_________________
286 стр. Часть 5. Полезные особенности
Функция parseString( ) связывает с символьной строкой объект istringstream. Программа считывает символы из строки до достижения символа '.' ( или конца строки ) при помощи функции-члена getline( ), после чего используются обычные операторы извлечения из потока для чтения номера счёта и баланса. Чтение выполнено успешно, если inp.fail( ) возвращает false.
После вызова функции parseString( ) выполняется вывод в буфер обработанной информации. Результат работы программы выглядит следующим образом.
================
Chester, 12345 56.60
Имя = Chester,Счёт = 12345, Баланс = 56.6
Chester, 56.6 12345
================
Arthur, 34567 67.50
Имя = Arthur,Счёт = 34567, Баланс = 67.5
Arthur, 67.5 34567
================
Trudie, 56x78 78.90
Ошибка разбора строки
================
Valerie, 78901 89.10
Имя = Valerie,Счёт = 78901, Баланс = 89.1
Valerie, 89.1 78901
===============
Press any key to continue...
Обратите внимание, как программа способна восстановиться после ошибок во входном файле. Оцените также простоту функции parseString( ), использующей возможности класса istringstream.
Больше книг — больше знаний!
Заберите 20% скидку на все книги Литрес с нашим промокодом
ПОЛУЧИТЬ СКИДКУ