Почему fgets превосходит fscanf для безопасного чтения файлов на C

2

Перестаньте использовать fscanf для чтения текстовых файлов. Это ловушка. Если ваши данные не отформатированы идеально до последнего пробела, fscanf даст сбой, нарушит выравнивание и оставит вас отлаживать кошмар. Надежный путь? Откройте файл в режиме r, используйте fgets для захвата целых строк, а затем разберите нужные вам части.

Вот простой способ чтения файла и вывода его содержимого на экран без падения системы.

Логика здесь обманчиво проста. fgets считывает строку, до 1000 символов в этом буфере, и возвращает NULL только при достижении конца файла. Он выводит данные напрямую в stdout через printf. Обратите внимание на отсутствие \n в строке формата printf? Это сделано намеренно. fgets автоматически добавляет символ новой строки в конец прочитанной строки. Если вы добавите свой собственный \n, вы получите двойные интервалы. Более важно то, что если строка длиннее 1000 символов, fgets не добавит символ новой строки. Вы можете обнаружить это неполное чтение, проверив отсутствие \n, что является полезным приемом при работе с некорректными данными.

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

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

Если вы запустите это внутри цикла, close не сможет правильно освободить базовые ресурсы файла. В конечном итоге ваша программа исчерпает доступные дескрипторы файлов или место в памяти и аварийно завершит работу. fclose — единственный правильный способ закрыть файл. close — это короткий путь, ведущий к неработоспособности. Придерживайтесь стандартной библиотеки. Проверяйте свои буферы. Не позволяйте опечатке съесть вашу память.