2014-03-31 72 views
0

我使用Ubuntu 12.04
我想知道我可以用C如何c從控制檯讀取的中國和文件

setlocale(LC_ALL, "zh_CN.UTF-8"); 
    scanf("%s", st1); 
    for (b = 0; b < max_w;b++) 
    { 
    printf("%d ", st1[b]); 
    if (st1[b] == 0) 
     break; 
    } 

對於這個代碼讀中國,當我輸入英文,它輸出精,但如果我輸入中文像「的」,它輸出

Enter word or sentence (EXIT to break): 的 
target char seq : 
-25 -102 -124 0 

我想知道爲什麼在數組中有負值。
此外,我發現使用fscanf讀取的文件中的「的」字節與從控制檯讀取的不同。

+0

簡短的回答:在控制檯讀中國,你需要使用UTF庫,例如:'libconv'。 – jrd1

+0

爲什麼?這非常好。 @cloudygoose:有什麼問題?輸出是正確的。 – deviantfan

回答

2

UTF-8編碼字節數可變的字符。這就是爲什麼你看到三個字節的符號。

graphemica - 的,你可以看到的有,當你在UTF-8編碼它翻譯爲E79A84U+7684

您將每個字節單獨打印爲一個整數值。一個char類型可能會被簽名,當它被轉換爲一個整數時,你也可以得到負數。在你的情況,這是

  • -25 = E7
  • -102 = 9A
  • -124 = 84

可以打印字節十六進制值與%x或無符號整數%u,那麼你只會看到正數。

你也可以改變你的print語句

printf("%d ", (unsigned char) st1[b]); 

這將解釋字節的無符號數,並顯示您的輸出

231 154 132 0 
+0

即使'char'類型被實現爲'signed char',機器上的所有字符都將具有基本上正值。如何將它轉換爲'int'獲得負值? – ajay

+0

您可以將值E7解釋爲正值(即'unsigned char'),在這種情況下它是231.但是,當您將其解釋爲帶符號的負值(即,當您使用'signed char'時)時,它將會是打印爲-25。 –

0

對硬編碼特定區域名稱沒有必要(實際上它是有害的)。您可以讀取哪些字符與語言環境的語言無關(用於消息),並且任何使用UTF-8編碼的語言環境都應該可以正常工作。

最簡單的方法就是使用寬字符stdio函數(例如getwc)而不是字節型函數。否則,您可以讀取字節,然後使用mbrtowc來處理它們。