Visual Studio 2008控制臺(tái)程序無法輸出中文!?解決方法只需要設(shè)置一下區(qū)域即可。沒有設(shè)置區(qū)域前如下圖:

包含頭文件:#include <locale.h>
函數(shù):_tsetlocale(LC_ALL, _T("chs"));
設(shè)置區(qū)域后如下圖:

參考,摘自微軟MSDN
控制臺(tái)中的編碼程序員在對控制臺(tái)或“文本模式”應(yīng)用程序編程時(shí)可同時(shí)使用 Unicode 和 SBCS 或 DBCS 編碼。出于承襲方面的考慮,非 Unicode 控制臺(tái) I/O 函數(shù)使用控制臺(tái)代碼頁(默認(rèn)為 OEM 代碼頁)。Windows 中的所有其他非 Unicode 函數(shù)都使用 Windows 代碼頁。這意味著其他函數(shù)可能無法正確地處理由控制臺(tái)函數(shù)返回的字符串,反之亦然。例如,如果 FindFirstFileA 返回了一個(gè)包含某個(gè)非 ASCII 字符的字符串,WriteConsoleA 將無法正常地顯示該字符串。
要一直跟蹤哪些函數(shù)需要哪些編碼并正確轉(zhuǎn)換文本參數(shù)的編碼非常困難。函數(shù) SetFileApisToOEM、SetFileApisToANSI 和幫助程序函數(shù) AreFileApisANSI 的引入極大地簡化了此項(xiàng)工作。前兩個(gè)函數(shù)可接受或返回文件名稱,對 KERNEL32.dll 導(dǎo)出的非 Unicode 函數(shù)有效果。顧名思義,SetFileApisToOEM 將這些函數(shù)設(shè)置為接受或返回與當(dāng)前系統(tǒng)區(qū)域設(shè)置對應(yīng)的 OEM 字符集中的文件名稱,而 SetFileApisToANSI 用于為這些名稱恢復(fù)默認(rèn)值(Windows ANSI 編碼)。使用 AreFileApisANSI 可查詢到當(dāng)前選定的編碼。
利用 SetFileApisToOEM 可輕松地解決 WindFirstFileA(或 GetCurrentDirectoryA,或 Win32 API 的任何文件處理函數(shù))的結(jié)果無法直接傳送給 WriteConsoleA 這一問題:在調(diào)用 SetFileApisToOEM 后,WindFirstFileA 將返回以 OEM(而不是以 Windows ANSI 字符集)編碼的文本。但此解決方案并非應(yīng)對所有 Windows ANSI 與 OEM 不兼容情況的萬能良方。設(shè)想您需要從某個(gè)文件處理函數(shù)中獲取文本,然后將其輸出到控制臺(tái),接著用其他函數(shù)(不受SetFileApisToOEM 的影響)處理該文本。這種絕對理想的情況需要更改編碼。否則,您將需要調(diào)用 SetFileApisToOEM 以獲取用于控制臺(tái)輸出的數(shù)據(jù),然后調(diào)用SetFileApisToANSI 得到同一文本(使用另一種編碼)進(jìn)行內(nèi)部處理。另一種 SetFileApisToOEM 無法發(fā)揮作用的情況對命令行參數(shù)的處理:當(dāng)您的應(yīng)用程序的入口點(diǎn)為 main(而不是 wmain)時(shí),參數(shù)始終作為 Windows ANSI 字符串?dāng)?shù)組進(jìn)行傳遞。這一切顯然使編寫非 Unicode 控制臺(tái)應(yīng)用程序的程序員的工作變得更復(fù)雜了。
更為復(fù)雜的是為控制臺(tái)編寫的 8 位代碼需要處理兩種不同類型的區(qū)域設(shè)置。在編寫代碼時(shí),您可以使用 Win32 API 或 C 運(yùn)行時(shí)庫函數(shù)。Win32 API 的 ANSI 函數(shù)假定文本是針對當(dāng)前控制臺(tái)代碼頁(系統(tǒng)區(qū)域設(shè)置默認(rèn)定義的)編碼的。SetConsoleCP 和 SetConsoleOutputCP 函數(shù)可更改這些操作中使用的代碼頁。用戶可在命令提示符下調(diào)用 chcp or mode con cp select= 命令,這將會(huì)更改當(dāng)前控制臺(tái)的代碼頁。設(shè)置固定的控制臺(tái)代碼頁的另一種方法是用默認(rèn)的代碼頁集創(chuàng)建控制臺(tái)快捷方式(僅適用于東亞本地化版本的操作系統(tǒng))。 應(yīng)用程序應(yīng)能夠響應(yīng)用戶的操作。
C 運(yùn)行時(shí)庫(CRT 函數(shù))中區(qū)分區(qū)域設(shè)置函數(shù)可依照 (_w)setlocale 調(diào)用所定義的設(shè)置處理文本。如果代碼中未調(diào)用 (_w)setlocale,則 CRT 函數(shù)對這些操作使用 ANSI "C" 語言不變區(qū)域設(shè)置,這樣就丟失了特定于語言的功能。
該函數(shù)的聲明為:
setlocale( int category, const char *locale)或
_wsetlocale( int category, const wchar_t *locale)其中 "category" 用于定義受影響的特定于區(qū)域的設(shè)置(如果指定了 LC_ALL,則全部定義)。可變區(qū)域設(shè)置可以是顯式區(qū)域設(shè)置名稱或下面的某一項(xiàng):
".OCP" 指與當(dāng)前用戶區(qū)域設(shè)置對應(yīng)的 OEM 代碼頁
".ACP" 或 "" 指與當(dāng)前用戶區(qū)域設(shè)置對應(yīng)的 Windows 代碼頁
".OCP" 和 ".ACP" 參數(shù)始終引用用戶區(qū)域設(shè)置(而不是系統(tǒng)區(qū)域設(shè)置)的設(shè)置值。因此不能將它們用于設(shè)置 LC_CTYPE。此 "category" 定義了 Unicode 向 8 位轉(zhuǎn)換的規(guī)則和其他文本處理程序,必須遵循控制臺(tái)的設(shè)置(可使用 GetConsoleCP 和 GetConsoleOutputCP 訪問)。
對控制臺(tái)應(yīng)用程序最佳的長期解決方案是使用 Unicode,因?yàn)?Unicode 接口是針對 Win32 API 和 C 運(yùn)行時(shí)庫定義的。今后的編程模型仍需要您顯式地設(shè)置區(qū)域設(shè)置,但至少可肯定通過 Win32 和 CRT 看到的文本不再需要進(jìn)行代碼轉(zhuǎn)換。