Обычные символы в строке формата
Функция scanf() позволяет помещать в строку формата обычные символы. Вводимая с трока должна обеспечивать точное совпадение для обычных символов, отличных от пробельных. Например, предположим, что вы непредумышленно поместили занятую между двумя спецификаторами:
scanf("%d,%d", &n, &m);
Функция scanf() интерпретирует эту строку так, что вам придется набрать число, затем запя тую и, наконец, второе число. То есть вы должны вводить два целых числа следующим образом:
88, 121
Поскольку в строке формата запятая находится непосредственно после спецификатора %d, ее требуется набирать сразу после числа 88. Тем не менее, с учетом того, что scanf() пропускает пробельные символы, предшествующие целому числу, при вводе можно было бы набрать пробел или символ новой строки. Другими словами, показанные ниже варианты также будут приемлемыми:
88, 121
и
88,
121
Пробел в строке формата означает необходимость пропуска любых пробельных символов перед следующим элементом ввода. Например, оператор
scanf("%d,%d", &n, &m); принял бы любую из следующих входных строк:
88,121
88 ,121
88 , 121
Обратите внимание, что концепция “любые пробельные символы” охватывает также специальный случай отсутствия пробельных символов.
За исключением %с все остальные спецификаторы автоматически пропускают пробельный символ, предваряющий вводимое значение, так что оператор scanf ("%d%d", &n, &m) ведет себя точно так же, как scanf ("%d %d", &n, &m). Для спецификатора %c наличие или отсутствие символа пробела в строке формата не вносит никакой разницы. Например, если в строке формата спецификатору %с предшествует пробел, то функция scanf() пропускает все до появления первого непробельного символа. Таким образом, оператор scanf ("%с" , &ch) читает первый значащий символ, с которым сталкивается во введенных данных, a scanf (" %с", &ch) читает первый встреченный непробельный символ.
Символьные строки и форматированный ввод-вывод 149
Возвращаемое значение функции scanf()
Функция scanf() возвращает количество элементов, которые она успешно прочитала. Если не прочитано ни одного элемента, как бывает в случае набора нечисловой строки, в то время когда scanf() ожидает число, возвращается 0. При обнаружении условия, называемого “конец файла” (“end of file”), функция возвращает EOF. (EOF — это специальное значение, определенное в файле stdio.h. Обычно с помощью директивы #define константе EOF присваивается значение -1.) Мы рассмотрим признак конца файла в главе 6, а вопросы использования возвращаемого значения функции scanf() — позже в этой главе. После изучения операторов if и while вы сможете задействовать возвращаемое значение scanf() для обнаружения и обработки несогласованного ввода.
Модификатор * в функциях printf() и scanf()
И в printf(), и в scanf() модификатор * можно применять для изменения значения спецификатора, но делается это по-разному. Для начала давайте рассмотрим использование модификатора * в функции printf().
Предположим, что вы не хотите фиксировать ширину поля заранее, но желаете, чтобы ее определила сама программа. Это можно сделать, указав вместо числа, задающего ширину поля, модификатор *, но понадобится также добавить аргумент для сообщения функции, какой должна быть ширина поля. То есть при наличии спецификатора преобразования %*d список аргументов должен содержать значение для модификатора * и значение для d. Такой метод можно применять также со значениями с плавающей запятой, чтобы указывать точность и ширину поля. В листинге 4.16 приведен небольшой пример, демонстрирующий, как все это работает.
Листинг 4.16. Программа varwid.e

Переменная width определяет щирицу поля, а переменная number — это число, которое должно быть выведено. Поскольку модификатор * предшествует d в спецификаторе, значение width находится раньше значения number в списке параметров функции printf(). Подобным образом значения width и precision предоставляют необходимую информацию для форматирования для вывода значения weight. Взгляните на пример выполнения этой программы:
150 Глава 4
Введите ширину поля:
6
Значение равно: 256:
Теперь введите ширину и точность:
8 3
Вес = 242.500 Готово!
В этом случае ответом на первый вопрос было число 6, поэтому 6 используется для ширины поля. Второй ответ привел к установке ширины поля в 8 и отображению 3 цифр справа от десятичной точки. В целом программа могла бы принять решение относительно значений для этих переменных после анализа значения weight.
Читать дальше