2012-10-28 54 views
3

我想這個標題可以說明一切。如何在C中正確識別不同的行結束符?

我在Windows 7上編寫了一個C程序,使用g ++和Notepad ++來比較文件的內容。該文件的

內容:

simple 
file with lines 

的文件已在windows風格CRLF行結束。

我數的時候使用這個代碼的文件長度:

fseek(file, 0, SEEK_END); 
size = ftell(file); 
fseek(file, 0, SEEK_SET); 

我得到。

當我將行結束符更改爲Unix格式LF(使用Notepad ++)時,我得到長度。

這比較兩個文件時會產生一種問題。這就是爲什麼我問,如果有方法來確定給定的文件是否有LF或CR或CRLF。

我知道我可以區分CR和LF,LF的ASCII代碼是10,CR的代碼是13,或者LF是'\ n',CR是'\ r'。

但是,當讀取char後面的文件字符時,我總是會得到LF(ascii 10),即使存在CRLF也是如此。

我希望我說清楚。謝謝。

+1

然後只需讀取文件並計算字符而不使用'ftell'。 'ftell'返回文件中的字節數,這只是你*不*想*的東西;你想要*字符數*。 – Bakuriu

回答

2

這是閱讀文本和二進制模式文件之間的區別。

在文本模式下(打開相關參數fopen(file, "r"),然後getc等),所有行結束被讀爲一個字符。如果您以二進制模式讀取,例如fopen(file, "rb")然後你會得到實際的字節,你會看到CRLF和CR不同。 fseek將使用實際的字節數,因此可以看到行尾的差異。

而唯一的方法是讀取兩種不同方式的文件,看看是否有CRLF對或大小不同,或者實際上只是看看是否有LF,因爲我不認爲任何電流主要的操作系統使用它作爲線路啓動。

+0

謝謝你,爲我工作! – Horkyze

1

除了馬克的回答,如果你需要爲已經被打開(如stdinstdout)文件句柄做到這一點,你可以用_setmode()

#include <fcntl.h> 
#include <io.h> 

... 

_setmode(fileno(stdin), _O_BINARY); 

這個工程提供任何輸入或輸出已經發生到那個文件句柄。順便提一句,_setmode()只存在於Windows和DOS上;在類Unix操作系統上(包括OS X以後的Mac OS版本),文件實際上始終以二進制模式打開,並且fopen(file, "...b")被接受但不起作用。在這些平臺上,一行結尾由單個字符\n編碼。

+1

_on Unix文件始終以二進制模式打開 - 或者說,Unix上的文本模式和二進制模式之間沒有區別。 '用...打開()'...b「'''''在C90和之前的C中是可移植的和標準的;它在Unix上被接受,但是在那裏沒有任何區別(當然) –

+0

@JohnMarshall:好點,我已經編輯澄清了。 –

+0

感謝非常有用的信息! – Horkyze