我的代碼需要使用很多fgetc(inp)
.
它在 windows 中沒有任何問題,但在 macOS 中程式會出錯。
發現問題是兩個系統換行符的字符數不一致造成的:macOS just \n
, windows is\r\n
所以我創建了一個新函式來替換fgetc(inp)
它讀取換行符
void getwhite() {
int white = fgetc(inp);
if (isspace(white) == 0) {
fseek(inp, -1, SEEK_CUR);
}
}
但它沒有按預期作業,在 windows 中仍然可以正常作業,macOS 仍然報錯
uj5u.com熱心網友回復:
而不是fseek()
,您應該使用ungetc()
推回從流中讀取的位元組:
int getwhite() {
int c = fgetc(inp);
if (!isspace(c)) {
ungetc(c, inp);
}
return c;
}
關于在 windows 和其他系統上處理行尾:由于遺留原因,windows 仍然使用 CR LR 序列來指示文本檔案中的行結束,并且 C 庫將這些序列透明地轉換為單個'\n'
位元組,以供將檔案作為文本讀取的程式,具有fopen()
或更低級別的open()
介面。
這使得檔案偏移量難以使用,因為從檔案中讀取的位元組數可能與檔案中的位元組偏移量不同,無法使用標準函式檢索:在文本模式下打開的流的long
回傳ftell()
值僅作為有意義的在文本模式下打開的同一檔案上傳遞給fseek()
for模式的數字。SEEK_SET
在文本流中以非零偏移量SEEK_CUR
和SEEK_END
模式查找具有未定義的行為,如 C 標準中所指定:
7.21.9.2
fseek
函式
概要#include int fseek(FILE *stream, long int offset, int whence);
說明
[...]對于文本流,要么
offset
應為零,要么offset
應為先前成功呼叫ftell
與同一檔案關聯的流上的函式所回傳的值,并且whence
應為SEEK_SET
.
如果您需要依賴檔案偏移量,您應該以二進制模式打開檔案并在您自己的代碼中顯式處理行尾。
Apple 作業系統過去將行尾表示為單個 CR 位元組,但在 10 多年前,當他們采用 Mach unix 兼容內核時,它們切換到了單個 NL 位元組。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/470507.html