2014-10-29 41 views
1

下面的代碼給出了一個非常奇怪的結果時:奇怪的ASCII響應(中國)試圖複製的代碼塊strlwr 13.12

#include <iostream> 
#include <fstream> 

using namespace std; 

ifstream f("f1.in"); 
ofstream g("f1.out"); 
char sir[255]; 
int i; 

char strlwr(char sir[]) //if void nothing changes 
{ 
    int i = 0; 

    for (i = 0; sir[i] != NULL; i++) { 
     sir[i] = tolower(sir[i]); 
    } 

    return 0; //if instead of 0 is 1 it will kinda work , but strlwr(sir) still needs to be displayed 
} 

int main() 
{ 
    f.get(sir, 255); 
    g << sir << '\n'; // without '\n' strlwr will no more maters 
    g << strlwr(sir); 
    g << sir; 
    return 0; 
} 

f1.in:

JHON HAS A COW 

f1.out:

䡊乏䠠十䄠䌠壞 
樳湯栠獡慍撓睯 

僅當我使用CAPS時才顯示此項。
我在Ubuntu 14,歐洲版本上使用Code :: Blocks 13.12。
我很想知道它爲什麼顯示這個。
我很想知道它是否給你同樣的東西。

+0

'f1.in'的內容是什麼?這聽起來可能是[mojibake]的結果(https://en.wikipedia.org/wiki/Mojibake)。 (即文本是ASCII碼,但是您的終端或輸出解析器認爲它是UTF-8) – 2014-10-29 14:00:07

+0

錐體是「JHON HAS COW」,全部大寫,結果顯示在f1.out中。我認爲ASCII值會改變,但我不知道程序中的位置,爲什麼如果我刪除'\ n'(endl),事情就不會再發生了。 Mojibake可能與此有關,但我不認爲這是問題所在。 – George 2014-10-29 15:42:59

+0

你用什麼來查看輸出? '貓f1.out'或使用文本編輯器? – 2014-10-29 17:18:13

回答

1

恭喜!你已經發現了mojibake!您的輸出文本是100%正確的,但無論您如何查看,都將其解釋爲unicode。

如果您將unicode輸出轉換爲十六進制數值,問題將變得清晰。 (代碼從this StackOverflow answer借來的。)

$ cat unicode.txt 
䡊乏䠠十䄠䌠壞 
樳湯栠獡慍撓睯 

$ cat unicode.txt | while IFS= read -r -d '' -n1 c; do printf "%02X\n" "'$c"; done 
484A 
4E4F 
4820 
5341 
4120 
4320 
574F 
0A 
686A 
6E6F 
6820 
7361 
6120 
6320 
776F 
0A 

第二個命令讀取由字符文件的字符,並打印在十六進制小端形式。每個字符是兩個字節數據的原因是因爲輸入被理解爲UTF-16,一種2字節編碼。

如果您重新詮釋十六進制輸出爲單字節ASCII代替(和正確的字節順序),你可以看到你的程序做了工作:

$ cat unicode.txt | while IFS= read -r -d '' -n1 c; do printf "%02X\n" "'$c"; done 
484A ; JH 
4E4F ; ON 
4820 ; H 
5341 ; AS 
4120 ; A 
4320 ; C 
574F ; OW 
0A ; \n 
686A ; jh 
6E6F ; on 
6820 ; h 
7361 ; as 
6120 ; a 
6320 ; c 
776F ; ow 
0A ; \n 

要確定的問題是你的C++程序或收看節目,請嘗試運行以下命令xxd f1.out。如果它看起來像ASCII,那麼這是您的觀看節目錯誤。否則,這是您程序的錯誤,您應該查看setlocale和/或以二進制模式打開您的輸出文件。

無論採用哪種方法,您都應該將g<<strlwr(sir);更改爲strlwr(sir);。目前它正在爲您的輸出添加一個NULL字節,這可能是無意的。

+0

我看到了與strlwr()的東西,但我不明白爲什麼如果我改變g << strlwr(先生)只是strlwr(先生)一切工作,因爲它應該工作,我認爲NULL字節應該已經表明我0 ,至多,但我認爲這意味着2行之間的NULL字節正在改變一切。 – George 2014-10-30 16:15:11

+0

@George - *通常*它會寫入一個'0',但是您已經定義了函數來返回一個'char',而不是'int'。儘管'(char)0'和'(int)0'的值是相同的,但在將它們寫入文件時,它們的處理方式不同。 – 2014-10-30 17:21:05