Стефан Дэвис - С++ для чайников .
- Название:С++ для чайников .
- Автор:
- Жанр:
- Издательство:Издательский дом Вильямс. Компьютерное издательство Диалектика
- Год:2007
- Город:Москва
- ISBN:0-7645-6852-3, 978-5-8459-0723-3
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стефан Дэвис - С++ для чайников . краткое содержание
1
empty-line
4
С++ для чайников . - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Диски — медленные устройства, и чтобы вывод на диск меньше замедлял работу программы, fstream накапливает выводимые данные во внутреннем буфере. Класс выводит буфер на диск по его заполнении. Вставка же объекта endl заставляет сбросить на диск всё, что есть в буфере, независимо от его заполненности. Сбросить буфер без вывода символа новой строки можно при помощи явного вызова функции-члена flush( ) .
_________________
284 стр. Часть 5. Полезные особенности
►Подклассы strstream...285
Потоковые классы позволяют программисту разбивать входные данные на числа и массивы символов. Так называемые "строковые потоки" позволяют использовать операции, определённые для файлов в классах fstream , для строк в памяти. Соответствующие классы istringstream и ostringstream определены в заголовочном файле sstream .
«В старых версиях С++ эти классы назывались istrstream и ostrstream и были определены в заголовочном файле strstream.»
[ Советы ]
Строковые потоки используют ту же семантику, что и соответствующие базовые классы для файлов, как видно из приведённой далее демонстрационной программы.
/* StringStream — чтение и разбор содержимого файла */
#include
#include
#include
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 << "\n" ;
if ( result == false )
{
cout << "Ошибка разбора строки\n" ;
continue ;
}
cout << "Имя = " << name << ","
<< "Счёт = " << accountNum << ", "
<< "Баланс = " << balance << endl ;
/* Выводим поля в другом порядке ( вставка ends гарантирует нуль-завершённость буфера ) */
ostringstream out ;
out << name << ", "
<< balance << " "
<< accountNum << ends ;
/* Вывод результата. Класс istringstream работает и с классом string, но пока что мы не будем использовать эту возможность */
string oString = out.str( ) ;
cout << oString << "\n" << endl ;
}
/* Пауза для того, чтобы посмотреть на результат работы программы */
system( "PAUSE" ) ; return 0 ;
}
Программа начинает работу с открытия файла Accounts.txt , содержащего информацию в формате
Имя, номер счёта, баланс, \n
В предположении, что файл открыт успешно, программа входит в цикл, считывающий файл построчно до его полного прочтения. Строки считываются при помощи функции-члена 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 .
►Работа с манипуляторами...287
Обычно потоки ввода-вывода для выведения чисел и символов используют формат по умолчанию, который оказывается вполне подходящим для решения большинства задач.
Например, мне совсем не нравится, когда общая сумма в моей любимой финансовой программе выводится как 249.600006 вместо ожидаемого 249.6 ( а ещё лучше — 249.60 ). Необходимо каким-то образом указать программе количество выводимых цифр после десятичной точки. И такой способ есть; более того, в С++ он не единственный.
«В зависимости от установок по умолчанию вашего компилятора, вы можете увидеть на экране 249.6. Однако хотелось бы добиться того, чтобы выводилось именно 249.60.»
[ Атас! ]
Во-первых, форматом можно управлять с помощью серии функций-членов объекта потока. Например, количество разрядов для отображения можно установить, используя функцию precision( ) :
#include
void fn( float interest , float dollarAmount )
{
cout << "Сумма в долларах = " ;
cout.precision( 2 ) ;
cout << dollarAmount ;
cout.precision( 4 ) ;
cout << interest
<< "\n" ;
}
_________________
287 стр. Глава 24. Использование потоков ввода-вывода
В этом примере с помощью функции precision( ) вывод значения dollarAmount устанавливается с точностью двух знаков после запятой. Благодаря этому вы можете увидеть на экране число 249.60 — именно то, что требовалось. Затем устанавливается вывод процентов с точностью четырёх знаков после запятой.
Читать дальшеИнтервал:
Закладка: