10247 widget 19.99
Введены значения: item# 10247 widget @$19.99
Можно ввести каждый элемент на отдельной строке. По умолчанию оператор ввода отбрасывает все разделяющие пустые символы: пробел, символ табуляции, символ перехода на новую строку, символ перевода страницы и символ возврата каретки. (О том, как отменить это поведение, см. в разделе 20.9.)
Пожалуйста, введите item_number, item_name и price:
10247
widget
19.99
Введены значения: item# 10247 widget @$19.99
При чтении ошибка iostream более вероятна, чем при записи. Если мы вводим такую последовательность:
// ошибка: item_name должно быть вторым
BuzzLightyear 10009 8.99
то инструкция
cin item_number;
закончится ошибкой ввода, поскольку BuzzLightyear не принадлежит типу int. При проверке объекта istream будет возвращено false, поскольку возникло состояние ошибки. Более устойчивая к ошибкам реализация выглядит так:
cin item_number;
if ( ! cin )
cerr "ошибка: введено некорректное значение item_number!\n ";
Хотя сцепление операторов ввода поддерживается, проверить корректность каждой отдельной операции нельзя, поэтому пользоваться таким приемом следует лишь тогда, когда ошибка невозможна. Наша программа теперь выглядит так:
#include iostream
#include string
int main()
{
int item_number;
string item_name;
double item_price;
cout "Пожалуйста, введите item_number, item_name и price: "
endl;
// хорошо, но легче допустить ошибку
cin item_number item_name item_price;
cout "Введены значения: item# "
item_number "
item_name " @$"
item_price endl;
}
Последовательность
ab c
d e
составлена из девяти символов: 'a', 'b', ' ' (пробел), 'c', '\n' (переход на новую строку), 'd', '\t' (табуляция), 'e' и '\n'. Однако приведенная программа читает лишь пять букв:
#include iostream
int main()
{
char ch;
// прочитать и вывести каждый символ
while ( cin ch )
cout ch;
cout endl;
// ...
}
И печатает следующее:
abcde
По умолчанию все пустые символы отбрасываются. Если нам нужны и они, например для сохранения формата входного текста или обработки пустых символов (скажем, для подсчета количества символов перехода на новую строку), то можно воспользоваться функцией-членом get() класса istream (обычно в паре с ней употребляется функция-член put() класса ostream; они будут рассмотрены ниже). Например:
#include iostream
int main()
{
char ch;
// читать все символы, в том числе пробельные
while ( cin.get( ch ))
cout.put( ch );
// ...
}
Другая возможность сделать это – использовать манипулятор noskipws.
Каждая из двух данных последовательностей считается составленной из пяти строк, разделенных пробелами, если для чтения используются операторы ввода с типами const char* или string:
A fine and private place
"A fine and private place"
Наличие кавычек не делает пробелы внутри закавыченной строки ее частью. Просто открывающая кавычка становится начальным символом первого слова, а закрывающая – конечным символом последнего.
Вместо того чтобы читать из стандартного ввода по одному символу, можно воспользоваться потоковым итератором istream_iterator:
#include algorithm
#include string
#include vector
#include iostream
int main()
{
istream_iterator string in( cin ), eos ;
vector string text ;
// копировать прочитанные из стандартного ввода значения
// в вектор text
copy( in , eos , back_inserter( text ) ) ;
sort( text.begin() , text.end() ) ;
// удалить дубликаты
vector string ::iterator it;
it = unique( text.begin() , text.end() ) ;
text.erase( it , text.end() ) ;
// вывести получившийся вектор
int line_cnt = 1 ;
for ( vector string ::iterator iter = text.begin() ;
iter != text.end() ; ++iter , ++line_cnt )
cout *iter
( line_cnt % 9 ? " " : " \n" ) ;
cout endl;
}
Пусть входом для этой программы будет файл istream_iter.C с исходным текстом. В системе UNIX мы можем перенаправить стандартный ввод на файл следующим образом (istream_iter – имя исполняемого файла программы):