fgetc,fputc,fgets和fputs是否需要以文本模式打开的文件,fread和fwrite需要以二进制模式打开的文件?

时间:2019-05-27 20:11:11

标签: c io

fgetcfputcfgetsfputs用于文件时,我是否需要确保已open将文件文本化模式不是二进制模式?

使用freadfwrite时,是否需要以二进制模式而非文本模式open编辑文件?

在Linux中,我认为没有区别。但是,如果在当前无法访问的Windows中怎么办?

2 个答案:

答案 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输入和输出函数是根据对fgetcfputc的重复调用来定义的。除了最上面的POSIX要求(主要是针对整个较大的操作而不是针对单个fgetc / fputc的粒度的锁定)之外,调用fputc或{{1}之间没有区别}自己循环执行,或使用fgetcfwrite进行等效操作。

如果您使用的C实现将文本文件与二进制文件对待的方式不同,则无论您使用哪种函数执行操作,该处理方式都将适用。