Приведем примеры ввода данных из входного потока с помощью функции scanf( ).
Предположим, что необходимо ввести со стандартного ввода следующие данные: десятичное число, одиночный символ и строку. Пусть во входном потоке присутствует дополнительная информация, необходимая для пояснения или идентификации вводимых данных. Например, вводимые данные могут иметь такой формат:
code: цифрастрока1 символ строка2
Набранные жирным шрифтом элементы (цифра, символ и строка2) должны быть введены в программу, а элементы, набранные курсивом, будут использоваться для контроля (code:) и комментария (строка1).
Контроль заключается в том, что во входном потоке должна присутствовать именно строка "code:" (без кавычек). Строка строка1 используется для комментирования вводимых данных, может иметь произвольную длину и пропускается при вводе. Отметим, что строка1 и строка2 не должны содержать внутри себя пробелов. Текст программы приводится ниже:
Рассмотрим форматную строку функции scanf( ):
Строка "code:" присутствует во входном потоке для контроля вводимых данных и поэтому указана в форматной строке. Спецификации преобразования задают следующие действия:
%d - ввод десятичного целого;
%*s - пропуск строки (строка 1 в приведенной выше форме ввода);
%с - ввод одиночного символа;
%s - ввод строки.
Приведем результаты работы программы для трех различных наборов входных данных.
1. Последовательность символов исходных данных:
Результат выполнения программы:
Значением переменной ret является код возврата функции scanf( ). Число 3 говорит о том, что функция scanf( ) ввела данные без ошибки и было обработано 3 входных поля (строки "code:" и "поле2" пропускаются при вводе).
2. Последовательность символов исходных данных:
Результат выполнения программы:
Обратите внимание на то, что во входных данных пропущена строка перед символом D, использующаяся как комментарий. В результате символ D из входного потока был (в соответствии с форматной строкой) пропущен, а из строки "asd" в соответствии с требованием спецификации преобразования %с был введен символ 'а' в переменную с. Остаток строки "asd" (sd) был введен в массив символов s. Код возврата (ret=3) функции scanf( ) говорит о том, что функция завершила свою работу без ошибок и обработала 3 поля.
3. Последовательность символов исходных данных:
Результат выполнения программы:
Вместо предусмотренной в форматной строке последовательности символов в данных входного потока допущена ошибка (набрано слово cod: вместо code:). Функция scanf( ) завершается аварийно (код возврата равен 0). Функция printf( ) в качестве результата напечатала случайные значения переменных i, с и s ("мусор").
Необходимо иметь в виду, что функция scanf( ), обнаружив какую-либо ошибку при преобразовании данных входного потока, завершает свою работу, а необработанные данные остаются во входном потоке. Если функция scanf( ) применяется для организации диалога с пользователем, то, будучи активизирована повторно, она дочитает из входного потока "остатки" предыдущей порции данных, а не начнет анализ новой порции, введенной пользователем.
Предположим, что программа запрашивает у пользователя номер дома, в котором он живет. Программа обрабатывает код возврата функции scanf( ) в предположении, что во входных данных присутствует одно поле.
При правильном вводе данных (введено целое десятичное число) результат будет следующий:
Предположим, что пользователь ошибся и ввел, например, следующую последовательность символов "@%". (Эти символы будут введены, если нажаты клавиши '2' и '5', но на верхнем регистре, т.е. одновременно была нажата клавиша <Shift>.) В этом случае получится следующий результат:
Ошибочный символ @ прерывает работу функции scanf( ), но сам остается во входном потоке, и вновь делается попытка его преобразования при повторном вызове функции в теле цикла while. Однако эта и последующие попытки ввода оказываются безуспешными, и программа переходит к выполнению бесконечного цикла. Необходимо до предоставления пользователю новой попытки ввода номера дома убрать ненужные символы из входного потока. Это предусмотрено в следующем варианте той же программы:
Теперь при неправильном вводе данных результат будет таким: