|
Программирование >> Поддержка объектно-ориентированного программирования
не затрагивая пользовательских программ. 10.3 ВВОД Ввод во многом сходен с выводом. Есть класс istream, который реализует операцию ввода >> ( ввести из - input from ) для небольшого набора стандартных типов. Для пользовательских типов можно определить функцию operator>>. 1 0.3.1 Ввод встроенных типов Класс istream определяется следующим образом: class istream : public virtual ios { ... public: istream& operator>>(char*); строка istream& operator>>(char&); символ istream& operator>>(short&); istream& operator>>(int&); istream& operator>>(long&); istream& operator>>(float&); istream& operator>>(double&); ... Функции ввода operator>> определяются так: istream& istream::operator>>(T& tvar) пропускаем обобщенные пробелы каким-то образом читаем T вtvar return *this; Теперь можно ввести в VECTOR последовательность целых, разделяемых пробелами, с помощью функции: int readints(Vector<int>& v) возвращаем число прочитанных целых for (int i = 0; i<v.size(); if (cin>>v[i]) continue; return i; слишком много целых для размера Vector нужна соответствующая обработка ошибки Появление значения с типом, отличным от int, приводит к прекращению операции ввода, и цикл ввода завершается. Так, если мы вводим 1 2 3 4 5. 6 7 8. то функция readints() прочитает пять целых чисел 1 2 3 4 5 Символ точка останется первым символом, подлежащим вводу. Под пробелом, как определено в стандарте С, понимается обобщенный пробел, т.е. пробел, табуляция, конец строки, перевод строки или возврат каретки. Проверка на обобщенный пробел возможна с помощью функции isspace() из файла <ctype.h>. В качестве альтернативы можно использовать функции get(): class istream : public virtual ios { ... istream& get(char& c); символ istream& get(char* p, int n, char =n); строка В них обобщенный пробел рассматривается как любой другой символ и они предназначены для таких операций ввода, когда не делается никаких предположений о вводимых символах. Функция istream::get(char&) вводит один символ в свой параметр. Поэтому программу посимвольного копирования можно написать так: main() char c; while (cin.get(c)) cout << c; Такая запись выглядит несимметрично, и у операции >> для вывода символов есть двойник под именем put(), так что можно писать и так: main() char c; while (cin.get(c)) cout.put(c); Функция с тремя параметрами istream::get() вводит в символьный вектор не менее n символов, начиная с адреса p. При всяком обращении к get() все символы, помещенные в буфер (если они были), завершаются 0, поэтому если второй параметр равен n, то введено не более n-1 символов. Третий параметр определяет символ, завершающий ввод. Типичное использование функции get() с тремя параметрами сводится к чтению строки в буфер заданного размера для ее дальнейшего разбора, например так: void f() char buf[100]; cin >> buf; подозрительно cin.get(buf,100,\n); надежно ... Операция cin buf подозрительна, поскольку строка из более чем 99 символов переполнит буфер. Если обнаружен завершающий символ, то он остается в потоке первым символом подлежащим вводу. Это позволяет проверять буфер на переполнение: void f() char buf[100]; cin.get(buf,100,\n); надежно char c; if (cin.get(c) && c!=\n) { входная строка больше, чем ожидалось Естественно, существует версия get() для типа unsigned char. В стандартном заголовочном файле <ctype.h> определены несколько функций, полезных для обработки при вводе: { return 0<=c && c<=127; } приведенных выше isalpha() isdigit() видим1й: ascii isalpha() isdigit() ispunct() Все они, кроме isascii(), работают с помощью простого просмотра, используя символ как индекс в таблице атрибутов символов. Поэтому вместо выражения типа ((a<=c && c<=z) (A<=c && c<=Z)) буква которое не только утомительно писать, но оно может быть и ошибочным (на машине с кодировкой EBCDIC оно задает не только буквы), лучше использовать вызов стандартной функции isalpha(), который к тому же более эффективен. В качестве примера приведем функцию eatwhite(), которая читает из потока обобщенные пробелы: istream& eatwhite(istream& is) char c; while (is.get(c)) { if (isspace(c)==0) { is.putback(c); break; return is; В ней используется функция putback(), которая возвращает символ в поток, и он становится первым подлежащим чтению. 10.3.2 Состояния потока С каждым потоком (istream или ostream) связано определенное состояние. Нестандартные ситуации и ошибки обрабатываются с помощью проверки и установки состояния подходящим образом. Узнать состояние потока можно с помощью операций над классом ios: class ios { ios является базов1м для ostream и istream ... public: int eof() const; int fail() const; int bad() const; int good() const; ... дошли до конца файла следующая операция будет неудачна поток испорчен следующая операция будет успешной Последняя операция ввода считается успешной, если состояние задается good() или eof(). Если состояние задается good(), то последующая операция ввода может быть успешной, в противном случае она будет неудачной. Применение операции ввода к потоку в состоянии, задаваемом не good(), считается пустой операцией. Если произошла неудача при попытке чтения в переменную v, то значение v не изменилось (оно не изменится, если v имеет тип, управляемый функциями члена из istream или int isalpha(char) int isupper(char) int islower(char) int isdigit(char) int isxdigit(char) int isspace(char) int iscntrl(char) int ispunct(char) int isalnum(char) int isprint(char) int isgraph(char) int isascii(char c) a..z A..Z A..Z a..z 0..9 0..9 a..f A..F \t возвращает конец строки и перевод формата управляющий символ в диапазоне (ASCII 0..31 и 127) знак пунктуации, отличен от
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |