Чому fgets перевершує fscanf для безпечного читання файлів на C

1

Перестаньте використовувати fscanf для читання текстових файлів. Це пастка. Якщо ваші дані не відформатовані ідеально до останньої прогалини, fscanf дасть збій, порушить вирівнювання та залишить вас налагоджувати кошмар. Надійний шлях? Відкрийте файл у режимі r, використовуйте fgets для захоплення цілих рядків, а потім розберіть потрібні частини.

Ось простий спосіб читання файлу та виведення його вмісту на екран без падіння системи.

`

Логіка тут оманливо проста. fgets зчитує рядок до 1000 символів у цьому буфері і повертає NULL тільки при досягненні кінця файлу. Він виводить дані безпосередньо в stdout через printf. Зверніть увагу на відсутність \n у рядку формату printf? Це зроблено навмисно. fgets автоматично додає символ нового рядка до кінця прочитаного рядка. Якщо ви додасте свій власний \n, ви отримаєте подвійні інтервали. Більш важливо те, що якщо рядок довший за 1000 символів, fgets не додасть символ нового рядка. Ви можете виявити це неповне читання, перевіривши відсутність \n, що є корисним прийомом при роботі з некоректними даними.

«Використовуйте fgets для читання кожного рядка, а потім розберіть потрібні частини.»

Існує одна критична помилка, яка збиває з пантелику навіть досвідчених розробників. Не опечатуйтесь у fclose, написавши замість нього close. Компілятор цього не помітить. Функція close існує, і для невеликих скриптів, які відкривають та закривають файл всього один або два рази, може здатися, що все працює нормально. Це брехня.

Якщо ви запустите це всередині циклу, close не зможе правильно звільнити базові ресурси файлу. Зрештою, ваша програма вичерпає доступні дескриптори файлів або місце в пам’яті і аварійно завершить роботу. fclose – єдиний правильний спосіб закрити файл. close – це короткий шлях, що веде до непрацездатності. Дотримуйтесь стандартної бібліотеки. Перевіряйте буфери. Не дозволяйте друкарській помилці з’їсти вашу пам’ять.