Windows平台下写文件的回车换行问题

Windows平台下写文件的回车换行问题

简介

Windows平台VC开发环境下,使用C标准库fopen&fprintf&fclose的时候,编译器已经做好了回车换行的特殊处理,我们只需要简单使用\n即可。

不合适的例子

先看这个代码:

int main(int argc, char* argv[])
{
    const char *file_name = "test.txt";
    FILE *fp = NULL;

    fp = fopen(file_name, "wt");
    fprintf(fp, "First line\r\n");
    fprintf(fp, "Second line\r\n");
    fprintf(fp, "The end.\r\n");
    fflush (fp);

    fclose(fp);

    return 0;
}

Coder因为知道Windows上面的换行,实际上是回车换行,而不是Linux上面只有换行一个字符。所以,上面使用\r\n做了特别处理。下面是生成的文件用NotePad++打开的样子:
NotePad++打开的样子

看起来比预期的多了一个换行。

再看UltraEdit打开的样子:
UE打开的样子

看起来稍微正常一些。

但无论怎样,说明文件是有些诡异的。为此,我们看其码流是什么样子的。如下:
UE二进制显示的样子

注意到,原本的回车换行,变成了回车+回车+换行,即自动多了一个回车。由此导致在Notepad++看起来是多了一个换行的。

原因分析

那么为什么会有这种情况呢?只需要看MSDN的说明:
MSDN对fopen的说明

就是说用文本模式读写文件的时候,标准库会自动对换行符做特殊处理。如果我们再做一遍,就多余了,产生了非预期的效果。

正确的做法

就是前面的代码不要\r\n,只需要一个\n即可。

再进步一点

在介绍后面的内容之前,我们进一步指出,如果读写文本文件,其实不需要特别强调那个”t”的(“wt”->”t”),即代码写成下面的样子即可:

int main(int argc, char* argv[])
{
    const char *file_name = "test.txt";
    FILE *fp = NULL;

    fp = fopen(file_name, "w");
    fprintf(fp, "First line\n");
    fprintf(fp, "Second line\n");
    fprintf(fp, "The end.\n");
    fflush (fp);

    fclose(fp);

    return 0;
}

这么做的好处,就是代码本身是可移植,或者说跨平台的。因为Linux平台上你不能用”t”(手头没有Linux环境,不好验证,不知道是否编译器牛到可以给出告警。),至少我一开始这么认为的。不过后来在旁边机器上验证了一下,发现没有任何告警。处理后的图片如下:

Ubuntu

不过,man fopen之后,也没有发现说支持”t”。这个图就不截了,因为后面还会再谈论标准库。

那么这个t是怎么来的呢?应该就是微软自定义的,从上面MSDN的截图可以证明罢。事实上,微软对标准库的改动是很普遍的,而TC的程序员一开始大都是VC开始玩的,久而久之,大家只知道VC,而不知道。。。(省略若干字)。

fopen的mode到底是什么样子

直接上图即可。

K&R的《C程序设计语言》:

K&R

每次提到这个K&R这个书,就很感概两点。第一,这K&R太牛了,怎么就写出了这么经典的书呢?!当时用的是第一版,白色封面。第二点,必然会想到当时上这课的超牛的老师,大家可以百度(王铮+重庆大学);讲授语言课是一门非常难的事情,但把这么难的事情又讲得那么牛,我还真遇到这么一位老师,非常幸运。(当时给我们上数据结构的也很牛,还和我们讲了国际象棋马如何跳不重复地遍历整个格子)。后来跑到HUST之后,又听过C++的课程,那简直没法比。——感谢CQU的美好四年!这么说,得贴个图表示一下。

表示一下哦

《C标准库》的说明:

C标准库

C99标准:

C99

题外话

markdown好用!

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值