для вывода символов есть двойник
Такая запись выглядит несимметрично, и у операции >> для вывода символов есть двойник под именем 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> определены несколько функций, полезных для обработки при вводе:
int isalpha(char) // 'a'..'z' 'A'..'Z' int isupper(char) // 'A'..'Z' int islower(char) // 'a'..'z' int isdigit(char) // '0'..'9' int isxdigit(char) // '0'..'9' 'a'..'f' 'A'..'F' int isspace(char) // ' ' '\t' возвращает конец строки // и перевод формата int iscntrl(char) // управляющий символ в диапазоне // (ASCII 0..31 и 127) int ispunct(char) // знак пунктуации, отличен от приведенных выше int isalnum(char) // isalpha() | isdigit() int isprint(char) // видимый: ascii ' '..'~' int isgraph(char) // isalpha() | isdigit() | ispunct() int isascii(char c) { return 0<=c && c<=127; }
Все они, кроме 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(), которая возвращает символ в поток, и он становится первым подлежащим чтению.
Содержание Назад Вперед