Я не использую scanf()
для интерактивного ввода данных пользователем; Я читаю все как текст, используя fgets()
, а затем анализирую ввод по мере необходимости, используя strtol()
и strtod()
для преобразования текста в числовые значения.
Один из примеров, где scanf()
падает, - это когда пользователь вводит неверное числовое значение, но его начальная часть действительна, что-то вроде следующего:
if (scanf("%d", &num) == 1)
{
// process num
}
else
{
// handle error
}
Если пользователь вводит «12e4», scanf()
успешно преобразует и присваивает «12» num, оставляя «e4» во входном потоке, чтобы запутать будущее чтение. Вход весь должен рассматриваться как фальшивый, но scanf()
не может уловить такую ошибку. OTOH, если я сделаю что-то вроде:
if (fgets(buffer, sizeof buffer, stdin))
{
int val;
char *chk;
val = (int) strtol(buffer, &chk, 10);
if (!isspace(*chk) && *chk != 0)
{
// non-numeric character in input; reject it completely
}
else
{
// process val
}
}
Я могу отловить ошибку на входе и отклонить ее перед использованием любой ее части. Это также лучше не оставляет мусор во входном потоке.
scanf()
- отличный инструмент , если , вы можете гарантировать, что ваш вклад всегда будет корректным.