Введення – це життєва сила будь-якої інтерактивної програми. Без нього ви просто використовуєте калькулятор у вакуумі. У мові програмування 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 з оголошення змінних. Подивіться, як компілятор почне кричати про невизначену змінну.
Видаліть крапку з комою. Перегляньте, як поширюється помилка синтаксису.
Видаліть фігурну дужку. Подивіться, як парсер збожеволіє.
Видаліть дужку. Спостерігайте за розгубленістю

































































