編輯:如果他們有同樣的問題,我會把問題留在這里供其他人閱讀;我在評論中被告知解決方案是 line[strcspn(line,"\r\n")]= 0。在我的作業系統課程中,我從未聽說過 \r,因此您可能遇到了同樣的問題這也可能對您有用。
因此,我已經閱讀了有關在使用 fgets 從文本檔案中讀取后如何擺脫 \n carachter 堆疊溢位的所有內容。
在我的 C 檔案中,我寫了這個:
const char *ESCAPE= "1a2b3c4e5d";
FILE *FP= fopen(backup.txt);
假設這是我在 backup.txt 中寫的:1a2b3c4e5d\n Mark
如您所見,第一行實際上與 ESCAPE 相同,不是為 \n 字符。現在讓我們看看下面的代碼,其中我嘗試在檔案中識別“1a2b3c4e5d”,并在洗掉 \n 字符后,執行 strcmp:
char line[64];
while(fgets(line, sizeof(line), FP)){
fprintf(stdout, "this is line lenght: %ld", strlen(line));
// It prints 12
line[strlen(line) -1]= 0; // Removing the new_line carachter;
fprintf(stdout, "This is line after getting rid of new_line: %ld\n", strlen(line));
// It prints 11.
fprintf("This is ESCAPE lenght: %ld\n", strlen(ESCAPE));
// It prints 10;
if(strcmp(line, ESCAPE) == 0){
fprintf(stdout, "I'm Here\n");
}
fgets 的第一次讀取將存盤在“1a2b3c4e5d\n”行中,據他說長度為 12。現在,我讀了 10 個字符和 new_line 一個,即 11,因為 strlen 不計算空終止符。我預計它是 11,因此第二次列印,在我洗掉 \n 之后,我預計長度是 10,而不是 11。
這意味著緩沖區內還有其他東西,但我真的不明白它是什么,當然,由于這個神秘的第 11 個字符,strcmp 永遠不會是真的。你知道它是什么嗎?我該如何解決?謝謝!
我試圖在 Stackoverflow 上尋找每一個答案。有些人甚至建議使用 strcspn,這是一個很好的發現(它甚至解決了緩沖區的一些麻煩情況),但由于某種原因,代碼在這種情況下不起作用。我找不到答案,因此我問了這個問題。
uj5u.com熱心網友回復:
很長的故事。短版本是,在 Unix 中,行以\n. 在 Windows 中,它們由\r\n
See for example here終止。
更長的版本更復雜。現在作為一個“unix 愛好者 windows-hater”的老極客,我應該告訴你 windows 是錯的,unix 是對的。但實際上,\r\n也是有道理的。從歷史的角度來看。
所有這些都可以追溯到計算機輸出是連接到列印機的串行線的時代。不是花哨的激光列印機,而更像是電子控制的打字機。這臺列印機使用協議接收一堆位元組(7 位位元組,第 8 個位元組用于奇偶校驗)。41 的意思是“列印一個 A”。48 的意思是“列印一個 0”。那就是眾所周知的ASCII碼。而這 128 個(又是 7 位)數字中的一些,除了“列印這個”之外,還有其他含義。例如 7 的意思是“敲響鈴鐺”(就像微波爐一樣,這樣當它準備好時有人會來看計算的結果:D)。8 表示后退一個字符(例如在先前列印的字符上列印其他內容)。等等。10 意味著(我說“意味著”。但所有這些仍然意味著。只是想想它當時所具有的腳踏實地的意義更有意義),向下走一行。和13“回到行首”。
因此,要在一行上列印“hello”,然后在另一行上列印“world”,您必須發送位元組 104、101、108、108、111、13、10、119、111、114、108 100。意思是“列印” “
\n只是\rC 中 10 和 13 的字符表示(然后幾乎在其他任何地方)。在 C 中,'\n'與10. 完全一樣0xA。只有 3 種不同的方式來表達完全相同的事情。
所以,現在,有些人可能(如在 unix 中)聲稱,向前送紙 1 行意味著回到那個新行的開頭(因此到目前為止是空的)。有人可能會說(如在 Windows 中),如果你只是向前走 1 行(跳過 13 aka \r),而不回到行首,你應該列印
hello
world
有些人甚至可能會說(就像 mac 人曾經做過的那樣,在他們成為 unix 人的變體之前)\r(到行首)意味著向前饋送一行。
我不是很年輕(我在職業生涯開始時更接近退休),此外,我很早就開始編碼(7 歲)。所以我編碼已經超過 40 年了。然而,我從來不知道輸出是實際列印機的時候(我知道物理的綠色終端,VT100 和它的型別。但即使是那些已經是某種列印機模擬器,沒有實際執行移動和觸發執行器的物理約束)。所以我不確定誰是真正正確的。我想這取決于列印機。但我知道,在我曾經擁有的機械打字機上(我認為大多數情況下也是如此),向前輸入一行并回傳到開頭的動作是以相同的手勢完成的。盡管也可以分別對兩件事中的每件事進行處理。所以,我想他們都沒事。請注意,Windows(甚至是 MS-DOS)從不知道那個時候。但它繼承自其他較舊的系統,例如 CP/M。
另外,我認為記憶體和磁盤使用的考慮也是一種方式,贊成說\n而不是\r\n(曾幾何時,這不會是一個荒謬的吝嗇。而且 windows 從來沒有以簡約著稱......)
所以,你看,這不是最近的辯論。這更像是一個“美國火車的寬度來自羅馬馬的驢子寬度”的故事。但與此同時,到 2022 年,世界仍然分為換行符由 10(又名\n)編碼的系統和由 13 然后 10(又名\r\n)編碼的系統
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/523664.html
標籤:C新队c字符串fgets
下一篇:ctrl x輸入是如何處理的?
