- •1.Ввод/вывод на консоль в стиле с
- •Форматный ввод / вывод на консоль
- •Спецификаторы преобразования
- •Ввод чисел
- •Ввод целых значений без знака
- •Чтение одиночных символов с помощью scanf()
- •Чтение строк
- •Ввод адреса
- •Спецификатор %n
- •Использование набора сканируемых символов
- •Пропуск лишних разделителей
- •Символы в управляющей строке, не являющиеся разделителями
- •Функции scanf() необходимо передавать адреса
- •Модификаторы форматат
- •Подавление ввода
- •Что внутри iostream.H
- •Использование cout
- •Использование символа-заполнителя
- •Управление цифрами значений с плавающей точкой
- •Вывод и ввод одного символа за один раз
- •Чтение ввода с клавиатуры по одному символу за раз
- •Чтение с клавиатуры целой строки
- •Что вам необходимо знать
1.Ввод/вывод на консоль в стиле с
Чтение и запись символов
Самыми простыми из консольных функций ввода/вывода являются getchar(), которая читает символ с клавиатуры, и putchar(), которая отображает символ на экране. Первая из этих функций ожидает, пока не будет нажата клавиша, а затем возвращает значение этой клавиши. Кроме того, при нажатии клавиши на клавиатуре на экране дисплея автоматически отображается соответствующий символ. Вторая же функция, putchar(), отображает символ на экране в текущей позиции курсора. Вот прототипы функций getchar() и putchar():
int getchar(void);
int putchar(int c);
Как видно из прототипа, считается, что функция getchar() возвращает целый результат. Однако возвращаемое значение можно присвоить переменной типа char, что обычно и делается, так как символ содержится в младшем байте. (Старший байт при этом обычно обнулен.) В случае ошибки getchar() возвращает EOF. (Макрос EOF определяется в <stdio.h> и часто равен -1.)
Что же касается putchar(), то несмотря на то, что эта функция объявлена как принимающая целый параметр, она обычно вызывается с символьным аргументом. На самом деле из ее аргумента на экран выводится только младший байт. Функция putchar() возвращает записанный символ или, в случае ошибки, EOF.
В следующей программе продемонстрировано применение getchar() и putchar(). В этой программе с клавиатуры вводятся символы, а затем они отображаются на другом регистре. То есть символы, вводимые на верхнем регистре, выводятся на нижнем, а вводимые на нижнем — выводятся на верхнем. Чтобы остановить программу, введите точку.
#include <stdio.h>
#include <ctype.h>
int main(void)
{
char ch;
printf("Введите какой-нибудь текст
(для завершения работы введите точку).\n");
do {
ch = getchar();
if(islower(ch)) ch = toupper(ch);
else ch = tolower(ch);
putchar(ch);
} while (ch != '.');
return 0;
}
(Эта программа не работает, правда, с кириллическими символами.)
Трудности использования getchar()
Использование getchar() может быть связано с определенными трудностями. Во многих библиотеках компиляторов эта функция реализуется таким образом, что она заполняет буфер ввода до тех пор, пока не будет нажата клавиша <ENTER>. Это называется построчно буферизованным вводом. Чтобы функция getchar() возвратила какой-либо символ, необходимо нажать клавишу <ENTER>. Кроме того, эта функция при каждом ее вызове вводит только по одному символу. Поэтому сохранение в буфере целой строки может привести к тому, что в очереди на ввод останутся ждать один или несколько символов, а в интерактивной среде это раздражает достаточно сильно. Хотя getchar() и можно использовать в качестве интерактивной функции, но это делается редко. Так что если предшествующая программа ведет себя не так, как ожидалось, то вы теперь знаете, в чем тут дело.
Альтернативы getchar()
Так как getchar(), имеющаяся в библиотеке компилятора, может оказаться неподходящей в интерактивной среде, то для чтения символов с клавиатуры может потребоваться другая функция. В стандарте языка С не определяется никаких функций, которые гарантировали бы интерактивный ввод, но их определения имеются буквально в библиотеках всех компиляторов С. И пусть в стандарте С эти функции не определены, но известны они всем! А известны они благодаря функции getchar(), которая для большинства программистов явно не подходит.
У двух из самых распространенных альтернативных функций getch() и getche() имеются следующие прототипы:
int getch(void);
int getche(void);
В библиотеках большинства компиляторов прототипы таких функций находятся в заголовочном файле <conio.h>. В библиотеках некоторых компиляторов имена этих функций начинаются со знака подчеркивания (_). Например, в Visual C++ компании Microsoft они называются _getch() и _getche().
Функция getch() ожидает нажатия клавиши, после которого она немедленно возвращает значение. Причем, символ, введенный с клавиатуры, на экране не отображается. Имеется еще и функция getche(), которая хоть и такая же, как getch(), но символ на экране отображает. И если в интерактивной программе необходимо прочитать символ с клавиатуры, то часто вместо getchar() применяется getche() или getch(). Вот, например, предыдущая программа, в которой getchar() заменена функцией getch():
#include <stdio.h>
#include <conio.h>
#include <ctype.h>
int main(void)
{
char ch;
printf("Введите какой-нибудь текст
(для завершения работы введите точку).\n");
do {
ch = getch();
if(islower(ch)) ch = toupper(ch);
else ch = tolower(ch);
putchar(ch);
} while (ch != '.');
return 0;
}
Когда выполняется эта версия программы, при каждом нажатии клавиши соответствующий символ сразу передается программе и выводится на другом регистре. А ввод в строках не буферизируется. И хотя в кодах в этой книге функции getch() и getche() больше не встречаются, но они вполне могут пригодиться в тех программах, которые напишете вы.
На заметку |
Тогда: когда писались эти слова, при использовании компилятора Visual C++ компании Microsoft функции _getch() и getch() были несовместимы с функциями ввода стандартного С, например, с функциями scanf() или gets(). Поэтому вам придется вместо стандартных функций использовать такие их специальные версии, как cscanf() или cgets(). Чтобы получить более подробную информацию, следует изучить документацию по Visual C++. |
Чтение и запись строк
Среди функций ввода/вывода на консоль есть и более сложные, но и более мощные: это функции gets() и puts(), которые позволяют считывать и отображать строки символов.
Функция gets() читает строку символов, введенную с клавиатуры, и записывает ее в память по адресу, на который указывает ее аргумент. Символы можно вводить с клавиатуры до тех пор, пока не будет введен символ возврата каретки. Он не станет частью строки, а вместо него в ее конец будет помещен символ конца строки ('0'), после чего произойдет возврат из функции gets(). На самом деле вернуть символ возврата каретки с помощью этой функции нельзя (а с помощью getchar() — как раз можно). Перед тем как нажимать <ENTER>, можно исправлять неправильно введенные символы, пользуясь для этого клавишей возврата каретки на одну позицию (клавишей backspace). Вот прототип для gets():
char *gets(char *cmp);
Здесь cmp — это указатель на массив символов, в который записываются символы, вводимые пользователем, gets() также возвращает cmp. Следующая программа читает строку в массив str и выводит ее длину:
#include <stdio.h>
#include <string.h>
int main(void)
{
char str[80];
gets(str);
printf("Длина в символах равна %d", strlen(str));
return 0;
}
Необходимо очень осторожно использовать gets(), потому что эта функция не проверяет границы массива, в который записываются введенные символы. Таким образом, может случиться, что пользователь введет больше символов, чем помещается в этом массиве. Хотя функция gets() прекрасно подходит для программ-примеров и простых утилит, предназначенных только для вас, но в профессиональных программах ею лучше не пользоваться. Ее альтернативой, позволяющей предотвратить переполнение массива, будет функция fgets(), которая описана в следующей главе.
Функция puts() отображает на экране свой строковый аргумент, после чего курсор переходит на новую строку. Вот прототип этой функции:
int puts(const char *cmp);
puts() признает те же самые управляющие последовательности[1], что и printf(), например, \t в качестве символа табуляции. Вызов функции puts() требует намного меньше ресурсов, чем вызов printf(). Это объясняется тем, что puts() может только выводить строку символов, но не может выводить числа или делать преобразования формата. В результате эта функция занимает меньше места и выполняется быстрее, чем printf(). Поэтому тогда, когда не нужны преобразования формата, часто используется функция puts().
Функция puts() в случае успешного завершения возвращает неотрицательное значение, а в случае ошибки — EOF. Однако при записи на консоль обычно предполагают, что ошибки не будет, поэтому значение, возвращаемое puts(), проверяется редко. Следующий оператор выводит фразу Привет:
puts("Привет");
В таблице 8.1 перечислены основные функции консольного ввода/вывода.
Таблица 8.1. Основные функции ввода/вывода |
|
Функция |
Ее действия |
getchar() |
Читает символ с клавиатуры; обычно ожидает возврат каретки |
getche() |
Читает символ, при этом он отображается на экране; не ожидает возврата каретки; в стандарте С не определена, но распространена достаточно широко |
getch() |
Читает символ, но не отображает его на экране; не ожидает возврата каретки; в стандарте С не определена, но распространена достаточно широко |
putchar() |
Отображает символ на экране |
gets() |
Читает строку с клавиатуры |
puts() |
Отображает строку на экране |
В следующей программе — простом компьютеризованном словаре — показано применение нескольких основных функций консольного ввода/вывода. Эта программа предлагает пользователю ввести слово, а затем проверяет, совпадает ли оно с каким-либо из тех слов, что находятся в ее базе данных. Если оно там есть, то программа выводит значение слова. Обратите особое внимание на использование косвенной адресации в этой программе. Чтобы легче было понять программу, прежде всего вспомните, что массив dic — это массив указателей на строки. Обратите внимание, что список должен завершаться двумя нулями.
/* Простой словарь. */
#include <stdio.h>
#include <string.h>
#include <ctype.h>
/* список слов и их значений */
char *dic[][40] = {
"атлас", "Том географических и/или топографических карт.",
"автомобиль", "Моторизоравонное средство передвижения.",
"телефон", "Средство связи.",
"самолет", "Летающая машина.",
"", "" /* нули, завершающие список */
};
int main(void)
{
char word[80], ch;
char **p;
do {
puts("\nВведите слово: ");
scanf("%s", word);
p = (char **)dic;
/* поиск слова в словаре и вывод его значения */
do {
if(!strcmp(*p, word)) {
puts("Значение:");
puts(*(p+1));
break;
}
if(!strcmp(*p, word)) break;
p = p + 2; /* продвижение по списку */
} while(*p);
if(!*p) puts("Слово в словаре отсутствует.");
printf("Будете еще вводить? (y/n): ");
scanf(" %c%*c", &ch);
} while(toupper(ch) != 'N');
return 0;
}
[1]Называются также ESC-последовательностями; в C/C++ — это комбинация символов, обычно используемая для задания неотображаемых символов и символов, имеющих специальное значение. Представление управляющих последовательностей начинается с обратной косой черты.