Ввод — это жизненная сила любой интерактивной программы. Без него вы просто используете калькулятор в вакууме. В языке программирования C основным инструментом для получения данных с клавиатуры является scanf. Он прост. Он повсеместен. Но также он славится своей безжалостностью к ошибкам.
Для простых скриптов или быстрых прототипов scanf справляется со своей задачей. Он читает из stdin (стандартного ввода). Если вы печатаете на клавиатуре, именно туда попадают ваши символы. Функция универсальна, но в ней отсутствует надежная обработка ошибок. Ей все равно, если вы введете букву, когда она ожидает число. Она просто зависнет или, что еще хуже, приведет к краху вашей программы. Именно поэтому она отлично подходит для простых задач, но не годится для программного обеспечения производственного уровня.
Синтаксис и амперсанд
Давайте рассмотрим самый простой возможный случай использования. Вам нужно целое число. Вы запрашиваете его. Вы сохраняете его.
scanf("%d", &b);
Вот и все. Два аргумента. Строка формата и целевая переменная.
%d сообщает scanf, что ожидается целое число. Это тот же заполнитель, который вы используете в printf. Переменная b должна быть объявлена как int. Если это не так, вы просите проблем.
Вот часть, которая каждый раз сбивает с толку новичков: амперсанд (& ).
&b — это не опечатка. Это указатель. Конкретно, это адрес переменной b. scanf принимает не значение, а ему нужно место в памяти, куда можно записать введенные данные. Забыли &. Ваш код может скомпилироваться. Но когда вы его запустите? Крах. Сегфолт. Пустота. Программа почти наверняка завершится аварийно, потому что попытается записать данные в случайный адрес памяти.
Флаги форматирования
scanf использует те же спецификаторы преобразования, что и printf. Если вы знаете один, вы знаете и другой. Но контекст имеет значение.
- Целые числа :
%d - Числа с плавающей точкой :
%f - Одиночные символы :
%c - Строки :
%s
Не путайте их. Замените %f на целое число, и вы получите мусор в данных или крах программы.
Почему scanf недостаточно
Вы можете цепочкой вызывать scanf для чтения нескольких значений.
Это работает для чисел. Это достаточно чисто. Но попробуйте прочитать целую строку текста? Это не сработает. scanf со спецификатором %s останавливается на первом пробельном символе. Он не читает всю строку целиком. И он не безопасно обрабатывает переполнение буфера.
Для реальных программ следует избегать использования scanf для ввода текста. Вместо этого используйте gets (которая устарела и опасна) или, что предпочтительнее, fgets. Эти функции читают строку за строкой в буфер. Получив строку, вы можете разобрать ее. Вы можете проверить наличие ошибок. Вы можете убедиться, что ввод выглядит как число, прежде чем пытаться преобразовать его. scanf пропускает этот шаг. Он предполагает, что вы знаете, что делаете. Обычно вы этого не знаете.
Намеренное разрушение
Лучший способ изучить C — не чтение документации. Это ломка компилятора.
Возьмите этот фрагмент:
Измените его. Сделайте хуже.
Удалите b из объявления переменных. Посмотрите, как компилятор начнет кричать об неопределенной переменной.
Удалите точку с запятой. Посмотрите, как распространяется ошибка синтаксиса.
Удалите фигурную скобку. Посмотрите, как парсер сойдет с ума.
Удалите скобку. Наблюдайте за растерянностью





































