将fgetc
,fputc
,fgets
和fputs
用于文件时,我是否需要确保已open
将文件文本化模式不是二进制模式?
使用fread
和fwrite
时,是否需要以二进制模式而非文本模式open
编辑文件?
在Linux中,我认为没有区别。但是,如果在当前无法访问的Windows中怎么办?
答案 0 :(得分:3)
[在Windows下使用 mingw 进行尝试后编辑]]
文本和二进制模式之间的区别仅在Windows下存在,不仅涉及 fwrite 和 fread ,而且还涉及 fgetc / fputc /.../ _read
/ _write
在文本模式下,如果文件包含序列\ r \ n,则在读取时仅会获得\ n,就像文件中不包含\ r一样。在二进制模式下,返回两个字符。请注意,fread Microsoft Docs和_read Microsoft Docs谈到了这种情况,但不幸的是,fget fgetwc Microsoft Docs
中的 fgetc 并没有说什么在写入时,如果以文本模式打开流,则每个\ n将以\ r \ n对的形式写入。请注意,替换对 fwrite 返回的大小没有影响。在二进制模式下,\ n不变地写入,没有添加\ r。请注意,fwrite Microsoft Docs和_write Microsoft Docs谈到了这种情况,但不幸的是,fputc fputwc Microsoft Docs
中的 fputc 并没有说什么幸运的是,在Windows下的文本模式下,读写功能是对称的,当以文本模式foo \ nbar进行写入时,如果仍以文本模式读取生成的文件,则会得到foo \ nbar,但是其中有foo \ r \ nbar文件。
所以
在使用fgetc,fputc,fgets和fputs作为文件时,是否需要确保以文本模式而非二进制模式打开了文件?
模式有影响
使用fread和fwrite时,是否需要以二进制模式而不是文本模式打开文件?
与其他功能类似,这是您的选择,但是如果文件也由其他工具读取/写入,则最好以文本模式打开文件,以防这些工具在读取时期望\ r在\ n之前或在写时产生一对。当然,您也可以在二进制模式下打开,并自己在\ n之前显式地写一个\ r。
如果该文件仅适合您使用C进行读取/写入,则最好始终以二进制模式打开,以在文件中仅包含您明确要求的文件。如果您使用 ftell / fseek ,则会强制执行此操作。
正如ftell Microsoft Docs中所述,ftell和_ftelli64可能无法反映以文本模式打开的流的物理字节偏移,因为文本模式会导致回车换行。
关于{em> fseek 的情况最糟糕,如fseek Microsoft Docs所述:
对于以文本模式打开的流,fseek和_fseeki64的使用受到限制,因为回车换行符的转换会导致fseek和_fseeki64产生意外的结果。保证可以在以文本模式打开的流上运行的唯一fseek和_fseeki64操作是:
相对于任何原始值的偏移量为0。
使用fseek或_ftseeki64时使用_ftelli64,从对ftell的调用返回的偏移值开始从文件的开头进行搜索。
答案 1 :(得分:1)
不。 所有 stdio输入和输出函数是根据对fgetc
或fputc
的重复调用来定义的。除了最上面的POSIX要求(主要是针对整个较大的操作而不是针对单个fgetc
/ fputc
的粒度的锁定)之外,调用fputc
或{{1}之间没有区别}自己循环执行,或使用fgetc
或fwrite
进行等效操作。
如果您使用的C实现将文本文件与二进制文件对待的方式不同,则无论您使用哪种函数执行操作,该处理方式都将适用。