百度“知道”中有人問以下代碼有什麼問題:
TCHAR tmpText[50];
sprintf(tmpText,"%d,%d", a, b);
TextOut(hDC, x, y, tmpText,lstrlen(tmpText));
代碼存在幾個與文字編碼有關的問題。提問者這樣寫,說明他對++中文字編碼相關的知識還是不太瞭解。由於字元編碼牽涉的問題比較多,我就決定寫一篇文章來說明一下。
char與wchar_t
char中存放的是多位元組型的字元,wchar_t中存放的是雙位元組型的字元,TCHAR在定義了_UNICODE時等同於wchar_t,在未定義_UNICODE時等同於char。
sprintf、wsprintf、_stprintf
sprintf是c++執行階段程式庫中的一個函數。c++ 執行階段程式庫處理字串的函數通常都有2個版本,一個處理多位元組型的字元,一個處理雙位元組型的字元。對於sprintf來說,它本身用於處理單位元組字元,其雙位元組字元版本名為wprintf。
為了使用方便,c++執行階段程式庫還為每個處理字串的庫函數定義了一個宏,sprintf對應的宏的名字為_stprintf,這個宏在定義了_UNICODE時等同於wsprintf,在未定義_UNICODE時等同於sprintf。
問題本身
sprintf處理單位元組字元,它就只能接收char類型的字串。所以,如果當前定義了_UNICODE宏,那麼tmpText中的字元的類型就是wchar_t. 它就不能傳給sprintf.
要使第二行代碼沒有問題,要麼把tchar換成char,要麼把sprintf換成tsprintf。由於TextOut接收tchar類型的字串,所以不能將tchar換成char,那隻能把sprintf換成tsprintf。 sprintf換成tsprintf後,其第二個參數也需要加上_T()宏,以便將其轉換為tchar類型。修改結果如下:
TCHAR tmpText[50];
_stprintf(tmpText,_T("%d,%d"), a, b);
TextOut(hDC, x, y, tmpText,lstrlen(tmpText));
如果項目中沒有定義_UNICODE宏,那麼整段代碼就可以通過編譯。但是這樣的寫法是有問題的,應該將代碼改為:
char tmpText[50];
sprintf(tmpText,"%d,%d", a, b);
TextOut(hDC, x, y, tmpText,lstrlen(tmpText));