C语言中以文本方式读写文件时换行符转换的注意事项
我们知道在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语言中以文本方式读写文件时换行符转换的注意事项的更多相关文章
- c++ 以二进制和以文本方式读写文件的区别
在c++项目开发中,时常涉及到文件读写操作.因此在这里先简单梳理和回顾一下文本模式和二进制模式在进行文件读写上的区别. 1.linux平台下文本文件和二进制文件的读写 在linux平台下进行文件读写时 ...
- ****使用ftp软件上传下载php文件时换行符丢失bug
在使用ftp软件上传下载php源文件时,我们偶尔会发现在本地windows下notepad++编辑器写好的php文件,在使用ftp上传到linux服务器后,php文件的换行符全部丢失了,导致php文件 ...
- C/C++中二进制与文本方式打开文件的区别
二进制与文本文件主要有两个大的区别: 1.换行符的区别: Windows平台下 对于Windows文本文件,它们使用回车和换行来表示换行符:如果以“文本”方式打开文件,当读取文件的时候,系统会将所有 ...
- C语言中的文本流与二进制流的区别
近期看到了文本流和二进制流的区别,书上讲的比较含糊,理解不透彻,于是细细琢磨了下,把心得跟大家分享一下: 一.首先回答,什么是文件,流 一个文件通常就是磁盘上的一段命名的存储区.比如 stdio.h ...
- 《用格式化(fprintf和fscanf函数)的方式读写文件》
//用格式化(fprintf和fscanf函数)的方式读写文件 [用格式化的方式向文件中写入数据]#include<stdio.h>#include<stdlib.h> int ...
- JavaScript在浏览器中把文本保存为文件的方法
JavaScript在浏览器中把文本保存为文件的方法 经过测试第二种方法可以保存更多的文本不至于卡死 var saveTextAsFile1 = function (text, fileName, s ...
- c# 读写文件时文件正由另一进程使用,因此该进程无法访问该文件
c# 读写文件时文件正由另一进程使用,因此该进程无法访问该文件,在IO处理上遇到了无法操作的问题. 文件"D:\log.txt"正由另一进程使用,因此该进程无法访问该文件. log ...
- C语言中一个语句太长用什么换行?
C语言中一个语句太长用什么换行? 5 C语言中一个语句太长用什么换行?比如我有一个printf语句很长很长,问了美观,我不想写在这一行了,要换到下一行,是不是在这行结尾的时候,要用个什么标识来表 ...
- C语言中宏定义(#define)时do{}while(0)的价值(转)
C语言中宏定义(#define)时do{}while(0)的价值 最近在新公司的代码中发现到处用到do{...}while(0),google了一下,发现Stack Overflow上早有很多讨论,总 ...
随机推荐
- mysql Seconds_Behind_Master
通过show slave status查看到的Seconds_Behind_Master,从字面上来看,他是slave落后master的秒数,一般情况下,也确实这样,通过Seconds_Behind_ ...
- Segment公司--整合数据进行分析
YC毕业生Segment获得1500万美元A轮融资 现在收集数据是每一个公司的必修课了,而且是从各种不同 API 上收集数据,但是你还要把这些数据整合起来才能发挥作用,Segment就能帮你整合各个平 ...
- Boost字符串处理
(1):Boost学习之格式化输出--format: 原文链接:http://www.cnblogs.com/lzjsky/archive/2011/05/05/2037327.html 此文非常详细 ...
- getopt_long 函数
getopt_long, getopt_long_only -- 命令行解析函数,支持长选项解析 [说明]getopt_long/getopt_long_only是getopt的泛集,getopt ...
- javaee字节流文件复制
package Zy; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.Fil ...
- vue中使用mui的extra icon问题
1. 元素类名更改 2. mui下的fonts文件夹中添加mui-icons-extra.ttf文件 3. mui下的css文件中添加icons-extra.css文件 4. main.js中导入im ...
- [SHOI2012]信用卡凸包(凸包+直觉)
这个题还是比较有趣. 小心发现,大胆猜想,不用证明! 我们发现所谓的信用卡凸包上弧的长度总和就是圆的周长! 然后再加上每个长宽都减去圆的直径之后的长方形的凸包周长即可! #include<ios ...
- [网络流24题] 方格取数问题/骑士共存问题 (最大流->最大权闭合图)
洛谷传送门 LOJ传送门 和太空飞行计划问题一样,这依然是一道最大权闭合图问题 “骑士共存问题”是“方格取数问题”的弱化版,本题解不再赘述“骑士共存问题”的做法 分析题目,如果我们能把所有方格的数都给 ...
- maven引入jsp相关依赖
<!--引入Servlet开始--> <dependency> <groupId>javax.servlet</groupId> <artifac ...
- MyEclipse 2014 有用的几个快捷键
ctrl+h fileSearch ------------------------------------- MyEclipse 快捷键1(CTRL) ---------------------- ...