在项目程序中,用fgets()读一个文本文件,一行一行的读取,之前测试的所有的文件都没有问题,今天突然拿到一个文件测试时却出问题了,调试发现它并没有一行一行的读,但是用notepad++明明可以看到文件是一行一行的啊,又不是没有回车,纠结一会,发现这个错误的文件是mac格式的,关于unix/mac/dos-windows三种文本文件的格式的行尾区别,以下是搜索到的资料:
<strong>不同系统间的行尾表示</strong>
UNIX格式,每行的行尾都是用一个0x0a字符(换行字符LF)表示的,
而在WINDOWS/DOS下每行的行尾都是用0x0d 0x0a两个字符(回车字符CR,换行字符LF)表示的,
MAC机,每行的行尾都是0x0d字符表示,即回车字符CR。
<span style="color:#3333FF;">(经我用winhex查看,确实如此——yockie注)</span>
在很多计算机语言中, <CR>表示为字符或字符串是\r, 而<LF>表示为字符或字符中是\n.
而在printf这样的函数中, 如果你出现一个\n, 它却代表了一个逻辑上的意义, 即它代表在本地系统上的那种回车换行, 所以它在UNIX上只是<LF>, 但如果你在DOS上用诸如Truboc编程的话它输出的是<CR><LF>
<strong>所以不同系统之间传输交换文件的时候,会出现问题;</strong>
1)Unix或linux上有个小工具, 专门在两种文件格式之间进行转换, 叫unix2dos, dos2unix.或在
vim中, 如果你想把一个文件存为另一种文件格式, 只需:set fileformat=unix或等号后面是dos, mac即可, 接下来的存盘动作就会自动把你的文件存为指定平台的格式.
2)在UltraEdit的 File->Conversions(有些版本是在Format -> Convert to..)菜单中, 有三个子菜单项就是专供你在各种文本格式之间转换的.
必须先将UNIX文本格式转换为DOS格式的。UltraEdit的FILE菜单中提供了对单个文件进行这种转换的能力,也可以实现批量转换。在UE中选择Search | Search in files菜单,在Find框中填写^n(表示UNIX文件中的回车换行符号),在Replace with中输入^p(表示DOS文件中的回车换行符号),全部替换后,就可以实现批量替换了。
<strong>不同系统间ftp使用注意事项</strong>
一些ftp的客户端程序会自动进行各个平台的文本文件格式转换. 所以要注意你在ftp中用ls看看到的文件大小未必是你下载下来的文件大小. 上传过程也是一样.
如果你不想ftp这样自作主张只要用bin命令即可. 它会告诉ftp进行逐字节的二进制模式传输.
[以上内容转自:http://hi.baidu.com/dongfangronger/blog/item/a46e56f0fd2129e27709d70f.html]
这就找到原因了,应该是fgets()函数是以读到'\n'为行结束标识(因为windows格式和unix格式的文本文件都能一行一行的读取),所以对于'\r'它并不识别为行结束标识。我是通过将mac格式文件转换为windows格式或unix格式来解决这个问题的。
当然还有其他的一些方法,例如在http://stackoverflow.com/questions/2061334/fgets-linux-vs-mac这里提到了用getdelim()或getline()函数来解决这个问题,因为在这两个函数中用个参数表示终结符,也就是说自己说明什么字符是终结符。不过我没有尝试。我想如果要做到通用的话,还得判断文本文件是什么格式的文件,也好知道传入哪一个终结符的参数。