我们知道在UNIX下是没有回车符(\r)的,只有换行符(\n),而C语言诞生于UNIX(Linux即面向开源的UNIX,Mac OS也是UNIX发展而来的,而Windows是从MS-DOS发展而来,与前两者不同),所以C语言的源代码文件中也是以 \n 表示换行。

所以总结一下:

Windows下换行采用 \r\n 表示,全称回车换行符。

UNIX(Linux)下换行采用 \n 表示,即换行符。

Mac OS下换行采用 \r 表示,即回车符。

所以,当C语言在Windows下以文本方式读取文件就会出现一个转换,看如下代码:

FILE * f1;
f1 = fopen("utf8.txt", "r");
/*
"utf8.txt"文件的十六进制结构如下:
41 42 43 0D 0A 44 44 4B
*/
fseek(f1, , SEEK_SET);
printf("%x\n", getc(f1));
printf("%x\n", getc(f1));
fclose(f1);

输出结果:

a
44
Press any key to continue

解释:当我们把文件指针通过fseek函数移到位置 3 时,文件指针指向了回车符(0x0D),然后我们用getc函数读取当前文件指针所指的字节时,C语言会把Windows下表示换行的0x0D和0x0A两个字节看成UNIX下表示换行的0x0A一个字节,所以,此时getc函数返回的是0x0A这个值。故,这次的getc函数读完后文件指针向后偏移两个字节,导致了下一个的getc返回的是0x44。

同理,当C语言在Windows下工作时,用putc向文件输入 \n 时会被自动转成 \r\n,如下代码:

FILE * f1;
f1 = fopen("new.txt", "w");
putc('\n', f1);
fclose(f1);

"new.txt"文件的十六进制结构:

0D 0A

解释:上述代码会在当前目录创建一个新文件"new.txt",并以文本方式只写模式打开文件流,然后通过putc向该文件输入字符 \n,这时C语言会自动把 \n 转为 \r\n,原理同上。

注意的是:C语言是否自动转换 \n 与 \r\n 取决于编译C语言程序时所在的系统,也同理在Mac OS下,C语言会自动发生 \n 与 \r的转换。

当然,这种情况是不会发生转换的:

FILE * f1;
f1 = fopen("utf8.txt", "r");
/*
该文件的十六进制结构如下:
31 32 33 0A 0D
*/
fseek(f1, , SEEK_SET);
printf("%x\n", getc(f1));
printf("%x\n", getc(f1));
fclose(f1);

输出结果:

a
d
Press any key to continue

解释:因为只有在Windows下编译的C程序,并且以文本方式打开一个文件,并且读取的0x0D后面紧跟着0x0A才会发生转换,也就是说0x0D 0x0A两个字节必须作为一个整体出现,显然,上述代码例子颠倒了 \r\n 的顺序。

另外,在Mac OS下编译的C程序,以文本方式读取一个以 \n 表示换行的文件时,也是不会发生 \r 与 \n的转换的,只有该文件以 \r 表示换行时才会发生 \r 与 \n的转换。

C语言中以文本方式读写文件时换行符转换的注意事项的更多相关文章

  1. c++ 以二进制和以文本方式读写文件的区别

    在c++项目开发中,时常涉及到文件读写操作.因此在这里先简单梳理和回顾一下文本模式和二进制模式在进行文件读写上的区别. 1.linux平台下文本文件和二进制文件的读写 在linux平台下进行文件读写时 ...

  2. ****使用ftp软件上传下载php文件时换行符丢失bug

    在使用ftp软件上传下载php源文件时,我们偶尔会发现在本地windows下notepad++编辑器写好的php文件,在使用ftp上传到linux服务器后,php文件的换行符全部丢失了,导致php文件 ...

  3. C/C++中二进制与文本方式打开文件的区别

    二进制与文本文件主要有两个大的区别: 1.换行符的区别: Windows平台下  对于Windows文本文件,它们使用回车和换行来表示换行符:如果以“文本”方式打开文件,当读取文件的时候,系统会将所有 ...

  4. C语言中的文本流与二进制流的区别

    近期看到了文本流和二进制流的区别,书上讲的比较含糊,理解不透彻,于是细细琢磨了下,把心得跟大家分享一下: 一.首先回答,什么是文件,流 一个文件通常就是磁盘上的一段命名的存储区.比如 stdio.h ...

  5. 《用格式化(fprintf和fscanf函数)的方式读写文件》

    //用格式化(fprintf和fscanf函数)的方式读写文件 [用格式化的方式向文件中写入数据]#include<stdio.h>#include<stdlib.h> int ...

  6. JavaScript在浏览器中把文本保存为文件的方法

    JavaScript在浏览器中把文本保存为文件的方法 经过测试第二种方法可以保存更多的文本不至于卡死 var saveTextAsFile1 = function (text, fileName, s ...

  7. c# 读写文件时文件正由另一进程使用,因此该进程无法访问该文件

    c# 读写文件时文件正由另一进程使用,因此该进程无法访问该文件,在IO处理上遇到了无法操作的问题. 文件"D:\log.txt"正由另一进程使用,因此该进程无法访问该文件. log ...

  8. C语言中一个语句太长用什么换行?

     C语言中一个语句太长用什么换行? 5 C语言中一个语句太长用什么换行?比如我有一个printf语句很长很长,问了美观,我不想写在这一行了,要换到下一行,是不是在这行结尾的时候,要用个什么标识来表 ...

  9. C语言中宏定义(#define)时do{}while(0)的价值(转)

    C语言中宏定义(#define)时do{}while(0)的价值 最近在新公司的代码中发现到处用到do{...}while(0),google了一下,发现Stack Overflow上早有很多讨论,总 ...

随机推荐

  1. AssemblyInfo.cs 文件信息

    using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices ...

  2. webpack学习笔记(4)--webpack.config.js

    devtool参数 这个参数控制是否生成,以及如何生成source map,已经在官网的doc说明总结了. 下表总结了各个参数和使用的情况 devtool 构建速度 重新构建速度 生产环境 品质(qu ...

  3. SpringBoot-CommandLineRunner实现预操作

    前提:在使用SpringBoot构建项目时,我们通常需要做一些预先操作(类似开机自启动).而SpringBoot正好提供了一个简单的方式来实现–CommandLineRunner. CommandLi ...

  4. 如何在GitHub部署自己的个人网站

    前段时间在B站学习了怎样做一个静态网页(up主是  表严肃 ),朋友问我他能不能访问我的这个静态网页,我说还没把它挂到网上.今天看见一篇文章说可以在GitHub部署自己的个人网站,心血来潮,想做一个玩 ...

  5. 使用IDEA 中 实现springboot 热部署 (spring boot devtools版)

    第一步:添加springboot的配置文件 首先我先贴出我的配置 添加依赖包 <!-- spring boot devtools 依赖包. --> <dependency> & ...

  6. mybatis入门截图三

    ----------------------------------------------- <!-- 用户信息的综合查询 --> <select id="userlis ...

  7. jQuery(基本事件)

  8. Callable与Futrue创建线程

    接口callable <V>  类型参数  V-call方法的结构类型 public interface Callable<V> 返回结果并且可能抛出的异常的任务.实现者定义一 ...

  9. 【转】C# ArcgisEngine开发中,对一个图层进行过滤,只显示符合条件的要素

    有时候,我们要对图层上的地物进行有选择性的显示,以此来满足实际的功能要求. 按下面介绍的方法可轻松实现图层属性过滤显示: 1.当图层已经加载时 private void ShowByFilter(Ax ...

  10. Linux下I/O复用 Select与Poll

    Select #include <sys/time.h>#include <sys/types.h>#include <sys/unistd.h> int sele ...