Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка-ТП-С++.doc
Скачиваний:
1
Добавлен:
01.07.2025
Размер:
661.5 Кб
Скачать

4.2.2. Использование gets и getch для ввода

Использование scanf, однако, порождает другую проблему. Снова выполните программу, но теперь введите ваше имя и фамилию. Заметьте, что программа использует в своем ответе только имя. Почему? Потому, что введенный вами после имени пробел сигнализирует scanf о конце вводимой строки.

Возможны два способа решения этой проблемы. Вот первый из них:

void main()

{

char first[20], middle[20], last[20];

printf("Как Вас зовут: ");

scanf("%s %s %s", first, middle, last);

printf("Дорогой %s, или %s?\n", last, first);

}

Это означает, что имеется три компоненты имени; в примере функция scanf не пойдет дальше, пока вы действительно не введете три строки. Но что, если необходимо прочитать полное имя, как одну строку, включая пробелы? Вот второй способ решения:

void main

{

char name [60];

printf("Как вас зовут: ");

gets(name);

printf("Привет, %s\n", name);

}

Функция gets читает все, что вы набираете, до тех пор пока не нажмете Enter. Она не помещает Enter в строку; однако в конец строки добавляет нулевой символ (\0).

Наконец, есть еще функция getch. Она читает единственный символ с клавиатуры, не выдавая его на экран (в отличии от scanf и gets). Заметим, что у нее нет параметра ch; getch является функцией типа char, ее значение может быть непосредственно присвоено ch.

4.3. Потоковый ввод-вывод

Вы научились использовать функции printf и scanf для ввода и вывода данных. Функция printf служит для форматированного вывода на устройство вывода вроде монито­ра, а scanf, в свою очередь, для форматированного ввода. Однако, эти функции не лишены недостатков.

Синтаксис использования этих функций примерно одинаков:

printf(<строка формата>, <объект>, <объект>, ...);

scanf(<строка формата>, <адрес>, <адрес>, ...);.

Строка формата определяет, как следует обращаться с аргументами функции, количество которых, вообще говоря, может изменятся произвольно (от нуля и больше). Именно в этом и кроется проблема.

Строка формата может содержать литеры и параметры вроде %d (десятичный) и %s (строковый), помогающие функции разобраться в по­лученных аргументах. Точная информация о типах аргументов нужна компилятору для того, чтобы правильно извлекать переменные из стека (туда они помещаются при вызо­ве функции). Так как список переменных может иметь произвольную длину, то строка формата задает порядок, количество и тип аргументов.

Эта возможность передачи списков аргументов не дается даром, процедура обработки строки формата делает printf и scanf достаточно медленными (изучение весьма замысловатых правил составления формата тоже не назо­вешь детской забавой). Очевидно, для ввода и вывода необходимо было приду­мать что-то получше.

Cin и cout. Как ни удивительно, операция потокового вывода (ostream) « и операция потокового ввода (istream) » изначально были реализованы как надстройка над printf и scanf. Это может показаться странным, но справедливости ради следует сказать, что, как бы ни были неудобны эти функции, их работоспособность проверялась годами.

Обозначения cin и cout – это не функции и не операции. Это объекты, или экземпляры класса. Чтобы можно было их использовать, включите в ваш модуль заголовок <iostream.h>:

#include <iostream.h>

После этого с объектами cin и cout можно работать. Они обеспечивают в точности те же возможности, что и функции printf и scanf, но их симмет­ричный синтаксис гораздо проще, удобнее и существенно легче усваивается.

Для записи в устройство вывода используйте cout:

int birthday = 1974;

char *greetings = "Здравствуй, мир!";

cout « greetings «"Я родился в" « birthday «

"году" « endl;

Обратите внимание на однородность синтаксиса вне зависимости от типа данных. Здесь присутствуют целое число, переменная char*, литерная строка и еще какое-то endl, и все совершенно одинаковым образом. Вообще гово­ря, данные любого базового типа можно отправить на вывод тем же самым образом. Синтаксис cin почти идентичен:

int a = 0;

cout « "Сколько вам лет?" « endl;

cin » a;

Обозначение endl в приведенном выше фрагменте – это манипулятор потока ввода-вывода. Он выполняет ту же функцию, что и символ \n в программах на С++. И endl, и \n (новая стро­ка) посылают на вывод комбинацию возврат каретки–перевод строки.

Первоначально сами объекты cin и cout для ввода и вывода использовали функции printf и scanf, которые из-за своих списков аргументов неопределенной длины работают достаточно медленно. Разумеется, если медленную функцию, вро­де printf, использовать для создания другой, то в результате получится функция еще более медленная. И действительно, поначалу ввод/вывод через cin и cout происходил с удручающей скоростью. Теперь cin и cout более не используют printf и scanf и работают гораздо эффективнее. Использование этих объектов в программах делает работу более эффективной, а процесс программирования и отладки – более легким и понятным.