最近在 windows git bash 遇到執行程式時中文顯示亂碼的問題,但是在 windows cmd.exe 卻可以正常顯示,例如下圖用 ping 指令,當用 Ctrl-C 結束執行時,windows git bash 顯示亂碼。

為什麼會這樣,可以先來做一個實驗,將下面的程式用 cp950 的編碼儲存為 a.cpp 檔案。
- #include <cstdio>
-
- int main()
- {
- printf("中文");
- return 0;
- }
然後我們用 cl.exe 編譯這個程式,如果檔案編碼的確是用 cp950 儲存,編譯器不會有警告,反之則會有警告。

然後在 windows cmd.exe 跟 windows git bash 中執行編譯好的執行檔,會發現跟上面的 ping 指令一樣,windows cmd.exe 正常,windows git bash 亂碼。

究其原因,是因為 windows git bash 預設是使用 utf-8 編碼,當它遇到 cp950 編碼的中文,不知道怎麼顯示,於是就變亂碼,而 cmd.exe 預設就是 cp950,所以可以正確顯示。
windows 一些老舊的內建程式還在使用 cp950 輸出文字,例如上面的 ping 指令,如果每次要用到這些指令就要切到 cmd.exe,實在太麻煩了,不過還好 windows git bash 內建的一個工具 winpty 可以很好的解決這個問題。
官網上對 winpty 的描述如下。
winpty is a Windows software package providing an interface similar to a Unix pty-master for communicating with Windows console programs. The package consists of a library (libwinpty) and a tool for Cygwin and MSYS for running Windows console programs in a Cygwin/MSYS pty.
可以看到,其實 winpty 的本職工作是在 windows 上做一個類似 linux 虛擬終端的,只是剛好它有將 cp950 轉為 utf-8 輸出的功能而已。關於虛擬終端是甚麼,超過這裡討論的範圍,想了解的可以看網上這篇有詳細的講解,不想了解的也沒關係,只要知道它能幫我們解決windows git bash 遇到 cp950 的亂碼問題就好。
使用方法只要將指令放在 winpty 後面就可以,如下圖所示,可以看到用 winpty 之後 ping 指令就可以正常顯示中文了。
