Бьерн Страуструп. Язык программирования С++ Второе дополненное издание



Pdf көрінісі
бет188/256
Дата11.07.2022
өлшемі2,87 Mb.
#37591
1   ...   184   185   186   187   188   189   190   191   ...   256
Байланысты:
Бьерн Страуструп. Язык программирования С . М Бином, 2011

10.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& v) 
// возвращаем число прочитанных целых 

for (int i = 0; i
if 
(cin>>v[i]) 
continue; 
return 
i; 

// слишком много целых для размера Vector 
// нужна соответствующая обработка ошибки 

Появление значения с типом, отличным от int, приводит к прекращению операции ввода, и цикл ввода 
завершается. Так, если мы вводим 
1 2 3 4 5. 6 7 8. 
то функция readints() прочитает пять целых чисел 
1 2 3 4 5 
Символ точка останется первым символом, подлежащим вводу. Под пробелом, как определено в 
стандарте С, понимается обобщенный пробел, т.е. пробел, табуляция, конец строки, перевод строки 
или возврат каретки. Проверка на обобщенный пробел возможна с помощью функции isspace() из 
файла 


Бьерн Страуструп.
Язык программирования С++ 
 
262 
В качестве альтернативы можно использовать функции 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.
В стандартном заголовочном файле  определены несколько функций, полезных для обработки 
при вводе: 


Бьерн Страуструп.
Язык программирования С++ 
 
263 
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(), которая возвращает символ в поток, и он становится первым 
подлежащим чтению. 


Достарыңызбен бөлісу:
1   ...   184   185   186   187   188   189   190   191   ...   256




©emirsaba.org 2024
әкімшілігінің қараңыз

    Басты бет