Когда данные вводятся при помощи функции gets(), все символы, которые были
набраны на клавиатуре до нажатия Enter, становятся значением переменной. Когда
символ вводится с помощью функции getchar(), нажатие клавиши автоматически
приводит к присвоению соответствующего символа переменной.
Функция scanf() работает по-другому. Вместо того чтобы просто взять данные и
присвоить их переменной, scanf() прежде всего с помощью указателей формата
определяет, каким образом следует трактовать введенные символы.
Принято говорить, что scanf() получает данные из входного потока. Входным
потоком называется последовательность символов, поступающих из некоторого
источника. В случае функции scanf() источником служит клавиатура. После нажатия
клавиши Enter все данные, которые были введены к этому времени, передаются функции
scanf() в виде пока еще бессмысленного набора символов, в том же порядке, в каком их
набирали. Затем scanf() определяет, какие символы соответствуют типу, заданному
указателем формата, а какие следует игнорировать. Указатели формата называют
преобразователями символов, так как они берут исходные символы из входного потока и
преобразуют их в данные, относящиеся к определенному типу.
Функция scanf() игнорирует не содержащие информации знаки: пробелы, символы
табуляции, символы новой строки, кроме тех случаев, когда текущий тип данных
определен как char. Рассмотрим программу:
main()
{
int count;
puts("Пожалуйста, введите число: ");
scanf("%d", &count);
printf("Число равно %d", count);
}
Перед тем как ввести число, вы можете нажимать на клавишу пробела столько,
сколько хотите— Си будет игнорировать пробелы, в ожидании первого значимого
символа. Затем Си попытается преобразовать символы в соответствии с указателями
формата в строке формата функции scanf(). Если эти символы соответствуют формату (в
данном случае— если это цифры), они будут внесены в переменную. Ввод данных
прекратится, если встретится символ, формат которого не соответствует ожидаемому, то
есть он не является цифрой.
Какие символы программа расценивает как «подходящие», зависит от указателей
формата. Если стоит указатель %d, то «подходящими» являются только цифры и знак
«минус». Если поставить указатель %x, то соответствующими формату окажутся символы
0123456789ABCDE, так как все они используются при записи чисел в шестнадцатеричной
системе счисления. Если же стоит указатель %c, принимаются любые символы, даже
пробел внутри входного потока функция scanf() в этом случае не игнорирует. Если
написать инструкцию:
char letter;
scanf("%c", &letter);
и нажать клавишу пробела в начале последовательности значимых символов, scanf()
присвоит переменной значение пробел, игнорируя последующие символы. Поэтому, имея
дело с типом char, нельзя помещать пробелы перед другими символами.
Выбор соответствующих средств ввода данных
Раньше уже говорилось, что особенности работы функции scanf() делают весьма
вероятной ситуацию, когда, из-за несоответствия форматов, ввод игнорируется. Поэтому,
используя scanf(), очень важно давать пользователю четкие инструкции перед каждой
процедурой ввода.
Примечание: рассмотренные выше функции вызываются из библиотеки stdio.h.
Во многих системах символы, входящие во входной поток, помещаются в область
памяти, называемую буфером. Если функция scanf() прерывает работу преждевременно,