錯誤描述
一些程序在 VC6 下運行好好地,但是放到 VC2008 及更高版本 VC 下編譯卻報錯誤(以下僅以 VC2008 舉例,高版本 VC 類似),例如使用如下語句:
outtextxy(10, 20, "Hello World");
在 VC6 下可以成功編譯,但在 VC2008 下編譯后會有錯誤。
中文版錯誤提示如下:
error C2665: “outtextxy”: 2 個重載中沒有一個可以轉換所有參數類型
英文版錯誤提示如下:
error C2665: 'outtextxy' : none of the 2 overloads could convert all the argument types
同樣的,對於其他一些包含字符串調用的函數,例如 loadimage、drawtext 等,也會遇到類似問題。
錯誤原因
簡單來說,這是由於字符編碼問題引起的。
VC6 默認使用的 MBCS 編碼,而 VC2008 及高版本 VC 默認使用的 Unicode 編碼。以下詳細解釋這個問題:
用 char 表示字符時,英文占用一個字節,中文站用兩個字節。這樣有一個嚴重的問題:兩個連續字節,究竟是兩個英文字符,還是一個中文字符?為了解決這個問題,Unicode 編碼誕生了。Unicode 編碼不管中文英文都用兩個字節表示。
對於 MBCS 編碼,字符變量用 char 定義。
對於 Unicode 編碼中,字符變量用 wchar_t 定義。
為了提高代碼的自適應性,微軟在 tchar.h 里面定義了 TCHAR,而 TCHAR 會根據項目定義的編碼,自動展開為 char 或 wchar_t。
在 Windows API 和 EasyX 里面的大多數字符串指針都用的 LPCTSTR 或 LPTSTR 類型,LPCTSTR / LPTSTR 就是“Long Point (Const) Tchar STRing”的縮寫。所以可以認為,LPCTSTR 就是 const TCHAR *,LPTSTR 就是 TCHAR * 。
於是,在 VS2008 里面,給函數傳遞 char 字符串時,就會提示前述錯誤。
解決方案
解決方法有多個,目的一樣,都是讓字符編碼相匹配。
方法一:將所有字符串都修改為 TCHAR 版本。
簡單來說需要注意以下幾點:
1. 在程序中使用 #include <tchar.h> 添加對 TCHAR 的支持。
2. 對於字符串,例如 "abc" 用 _T("abc") 表示。就是加上 _T("")。
3. 定義字符變量時,將 char 換成 TCHAR。
4. 操作字符串的函數也要換成相應的 TCHAR 版本,例如 strcpy 要換成 _tcscpy。(詳見 MSDN)
方法二:在代碼中取消 Unicode 編碼的宏定義,讓后續編譯都以 MBCS 編碼進行。
方法很簡單,只需要在代碼頂部增加以下代碼:
#undef UNICODE
#undef _UNICODE
這樣就可以取消 Unicode 編碼的宏定義,讓整個項目以 MBCS 編碼編譯。
方法三:在 VC2008 里面,將項目屬性中的字符編碼修改為 MBCS。
以下分別列舉中英文兩種版本的 VC2008 的操作步驟:
在中文版 VC2008 中的操作方法如下:點菜單“項目-> xxx 屬性...”(或右擊項目名稱,選擇“屬性”,或按 Alt + F7 也可以打開項目屬性),點左側的“配置屬性”,在右側的設置中找到“字符集”,修改默認的“使用 Unicode 字符集”為“使用多字節字符集”。
在英文版 VC2008 中的操作方法如下:點菜單“Project -> xxx Properties...”(或右擊項目名稱,選擇 Properties,或按 Alt + F7 也可以打開項目屬性),點左側的“Configuration Properties”,在右側的設置中找到“Character Set”,修改默認的“Use Unicode Character Set”為“Use Multi-Byte Character Set”。
設置完畢后,再次編譯就可以看到問題已經解決。