Выбрать главу

istream_iter istream_iter.C

(Для других систем необходимо изучить документацию.) В результате программа выводит:

!= " " " \n" #include % ( ) *iter ++iter

++line_cnt , 1 9 : ; algorithm iostream.h

string vector = ::difference_type ::iterator ? allocator

back_inserter(

cin copy( cout diff_type eos for in in( int

istream_iterator it iter line_cnt main() sort( string test test.begin()

test.end() test.erase( typedef unique( vector { }

(Потоковые итераторы ввода/вывода iostream рассматривались в разделе 12.4.)

Помимо предопределенных операторов ввода, можно определить и собственные перегруженные экземпляры для считывания в пользовательские типы данных. (Подробнее мы расскажем об этом в разделе 20.5.)

20.2.1. Строковый ввод

Считывание можно производить как в C-строки, так и в объекты класса string. Мы рекомендуем пользоваться последними. Их главное преимущество – автоматическое управление памятью для хранения символов. Чтобы прочитать данные в C-строку, т.е. массив символов, необходимо сначала задать его размер, достаточный для хранения строки. Обычно мы читаем символы в буфер, затем выделяем из хипа ровно столько памяти, сколько нужно для хранения прочитанной строки, и копируем данные из буфера в эту память:

#include iostream

#include string.h

char inBuf[ 1024 ];

try

{

while ( cin inBuf ) {

char *str = new char[ strlen( inBuf ) + 1 ];

strcpy( str, inBuf );

// ... сделать что-то с массивом символов str

delete [] str;

}

}

catch( ... ) { delete [] str; throw; }

Работать с типом string значительно проще:

#include iostream

#include string.h

string str;

while ( cin str )

// ... сделать что-то со строкой

Рассмотрим операторы ввода в C-строки и в объекты класса string. В качестве входного текста по-прежнему будет использоваться рассказ об Алисе Эмме:

Alice Emma has long flowing red hair. Her Daddy says

when the wind blows through her hair, it looks almost

alive, like a fiery bird in flight. A beautiful fiery

bird, he tells her, magical but untamed. " Daddy, shush,

there is no such creature," she tells him, at the same time

wanting him to tell her more. Shyly, she asks, " I mean,

Daddy, is there?"

Поместим этот текст в файл alice_emma, а затем перенаправим на него стандартный вход программы. Позже, когда мы познакомимся с файловым вводом, мы откроем и прочтем этот файл непосредственно. Следующая программа помещает прочитанные со стандартного ввода слова в C-строку и находит самое длинное слово:

#include iostream.h

#include string.h

int main()

{

const int bufSize = 24;

char buf[ bufSize ], largest[ bufSize ];

// для хранения статистики

int curLen, max = -1, cnt = 0;

while ( cin buf )

{

curLen = strlen( buf );

++cnt;

// новое самое длинное слово? сохраним его

if ( curLen max ) {

max = curLen;

strcpy( largest, buf );

}

}

cout " Число прочитанных слов "

cnt endl;

cout " Длина самого длинного слова "

max endl;

cout " Самое длинное слово"

largest endl;

}

После компиляции и запуска программа выводит следующие сведения:

Число прочитанных слов 65

Длина самого длинного слова 10

Самое длинное слово creature,"

На самом деле этот результат неправилен: самое длинное слово beautiful, в нем девять букв. Однако выбрано creature, потому что программа сочла его частью запятую и кавычку. Следовательно, необходимо отфильтровать небуквенные символы.

Но прежде чем заняться этим, рассмотрим программу внимательнее. В ней каждое слово помещается в массив buf, длина которого равна 24. Если бы в тексте попалось слово длиной 24 символа (или более), то буфер переполнился бы и программа, вероятно, закончилась бы крахом. Чтобы предотвратить переполнение входного массива, можно воспользоваться манипулятором setw(). Модифицируем предыдущую программу:

while ( cin setw( bufSize ) buf )

Здесь bufSize – размер массива символов buf. setw() разбивает строку длиной bufSize или больше на несколько строк, каждая из которых не длиннее, чем bufSize - 1.

Завершается такая частичная строка двоичным нулем. Для использования setw() в программу необходимо включить заголовочный файл iomanip:

#include iomanip

Если в объявлении массива buf размер явно не указан:

char buf[] = "Нереалистичный пример";

то программист может применить оператор sizeof, но при условии, что идентификатор является именем массива и находится в области видимости выражения: