Требуются ли для `fgetc`,` fputc`, `fgets` и` fputs` файл, открытый в текстовом режиме, а для `fread` и` fwrite` требуется файл в двоичном режиме? - PullRequest
1 голос
/ 27 мая 2019

При использовании fgetc, fputc, fgets и fputs для файла, нужно ли мне убедиться, что я open редактировал файл в текстовом режиме, а не в двоичном режиме?

При использовании fread и fwrite нужно ли open редактировать файл в двоичном режиме, а не в текстовом режиме?

В Linux, я думаю, нет никакой разницы.Но что если в Windows, к которой у меня сейчас нет доступа?

Ответы [ 2 ]

3 голосов
/ 27 мая 2019

[редактировать после попытки под Windows, используя mingw ]

Разница между текстовым и двоичным режимом существует только в Windows и касается не только fwrite и fread , но также fgetc / fputc / ... / _read / _write

В текстовом режиме, если файл содержит последовательность \r \ n, когда вы читаете как, \ n получает только, если файл не содержит \ r.В двоичном режиме два символа возвращаются.Примечание fread Microsoft Docs и _read Microsoft Docs говорят об этом случае, но, к сожалению, ничего не сказано для fgetc в fget fgetwc Microsoft Docs

При записи, если поток открыт в текстовом режиме, каждый \ n записывается как пара \ r \ n.Обратите внимание, что замена не влияет на размер, возвращаемый fwrite .В двоичном режиме \ n записывается без изменений, \ r не добавляется.Примечание fwrite Документы Microsoft и _write Документы Microsoft говорят об этом случае, но, к сожалению, ничего не сказано для fputc в fputc fputwc Документы Microsoft

К счастью, в текстовом режиме под Windows функции чтения и записи симметричны, когда вы пишете в текстовом режиме foo \ nbar, а затем читаете полученный файл в текстовом режиме, вы получаете foo \ nbar, но есть foo \ r \ nbarв файл.

Итак

При использовании fgetc, fputc, fgets и fputs для файла, мне нужно убедиться, что я открыл файл в текстовом режиме, а не в двоичном режиме?

режим оказывает влияние

При использовании fread и fwrite нужно ли открывать файл в двоичном режиме, а не в текстовом режиме?

Как и для других функций, это ваш выбор, но если файл также читается / записывается другим инструментом, может быть лучше открыть его в текстовом режиме, если эти инструменты ожидают \ r перед \ n при чтенииили создание пары при записи.Конечно, вы также можете открыть в двоичном режиме и явно написать \ r перед a \ n самостоятельно.

Если файл предназначен только для чтения и записи с помощью C, возможно, лучше всегда открывать в двоичном видережим, чтобы иметь в файле только то, что вы просили явно.Это применяется, если вы используете ftell / fseek .

Как сказано в ftell Документы Microsoft ftell и _ftelli64 могут не отражать смещение физического байтадля потоков, открытых в текстовом режиме, потому что текстовый режим вызывает перевод перевода строки в обратном направлении.

Это наихудшее значение для fseek , как сказано в fseek Microsoft Docs :

для потоков, открытых в текстовом режиме, fseek и _fseeki64 имеют ограниченное использование, потому что переводы с переводом строки в начало строки могут привести к неожиданным результатам для fseek и _fseeki64.Единственные операции fseek и _fseeki64, которые гарантированно работают с потоками, открытыми в текстовом режиме:

  • Поиск со смещением 0 относительно любого из исходных значений.

  • Поиск в начале файла со значением смещения, возвращаемым из вызова ftell при использовании fseek или _ftelli64 при использовании _fseeki64.

1 голос
/ 28 мая 2019

Нет. Все функции ввода / вывода stdio определены в терминах повторных вызовов fgetc или fputc.Помимо требований POSIX сверху (в основном это блокировка для всей более крупной операции, а не для отдельной fgetc / fputc гранулярности), нет никакой разницы между вызовом fputc или fgetc в цикле самостоятельно или выполнениемэквивалентно fwrite или fread.

Если используемая реализация C обрабатывает текстовые файлы иначе, чем двоичные, эта обработка применяется независимо от того, какие функции вы используете для выполнения операций.

...