[問題][部份解決] 如何阻止Visual Studio改變字串編碼?
開發平台(Platform): (Ex: Win10, Linux, ...)
WindowXP Windows7
編譯器(Ex: GCC, clang, VC++...)+目標環境(跟開發平台不同的話需列出)
Visual Studio 2010~2015
問題(Question):
我在VS上面使用檔頭有BOM的UTF8程式碼
但是程式碼上的中文最後輸出都會變亂碼
輸出到console視窗、輸出成圖片、輸出到支援UTF8的GUI工具上
一樣的程式碼在MinGW上就很正常
我覺得程式碼裡的中文字是被編譯器轉成其他編碼的
因為我把中文字另外存在外部的XML等文字檔上就沒問題
(程式執行後才載入的字碼不會被編譯器更改)
請問我該修改Visual Studio上的哪個選項?
可以的話告訴我2012的做法
不然2010~2015的其中一版也可以
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 114.36.254.148
※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1505311897.A.A7E.html
→
09/13 22:38, , 1F
09/13 22:38, 1F
→
09/13 22:58, , 2F
09/13 22:58, 2F
→
09/13 23:06, , 3F
09/13 23:06, 3F
→
09/13 23:32, , 4F
09/13 23:32, 4F
→
09/13 23:35, , 5F
09/13 23:35, 5F
→
09/13 23:38, , 6F
09/13 23:38, 6F
→
09/14 00:03, , 7F
09/14 00:03, 7F
→
09/14 00:05, , 8F
09/14 00:05, 8F
把UTF8餵進ANSI API是沒有問題的,UTF8的賣點之一就是可以被當成char字串
至於Windows下std::cout跟fopen這種介面會無法吃UTF8字串則是底層實作的問題
微軟只支援你用wchar_t來完成那兩個功能(用WriteConsoleW跟_wfopen)
這不礙事,微軟有提供MultiByteToWideChar來幫忙將UTF8轉換成wchar_t字串
我的程式從外部讀取UTF8文件的字串就運作的好好的
檔案讀取介面沒道理會對外部文字做轉編碼處理
所以我才會認為是編譯階段被動手腳
順帶一提
我不建議_T("字串")這樣的寫法
現代Windows程式很少不用Unicode了
OS的資料夾名稱都已經預設用Unicode儲存了
_T算是舊時代過渡期留下的東西了
我現在偏向只用UTF8處理,所以也不會加L,必要時再轉就行了
不然使用C++11的raw string時會很醜
※ 編輯: eye5002003 (114.36.254.148), 09/14/2017 00:49:36
→
09/14 00:59, , 9F
09/14 00:59, 9F
→
09/14 01:01, , 10F
09/14 01:01, 10F
→
09/14 01:15, , 11F
09/14 01:15, 11F
→
09/14 01:19, , 12F
09/14 01:19, 12F
→
09/14 01:27, , 13F
09/14 01:27, 13F
→
09/14 01:32, , 14F
09/14 01:32, 14F
→
09/14 09:59, , 15F
09/14 09:59, 15F
推
09/14 11:15, , 16F
09/14 11:15, 16F
→
09/14 11:42, , 17F
09/14 11:42, 17F
→
09/14 11:43, , 18F
09/14 11:43, 18F
_T是怕環境不支援Unicode才留的後路,你真的有這需要你就用吧Schottky
a27417332其實我的UTF8程式碼有在檔頭加BOM做為提示
VS沒有誤解我的中文字,只是VS自作主張改成其他編碼了
MinGW跟Linux下都是繼續當UTF8
我現在研究進度是發現VS把字串改成Big5了,james你說對了
我還是不知道如何叫VS讓字串維持UTF8
shadow你說的修改Character set不會改變結果,VS依然輸出big5
以下是個簡單的測試程式,有興趣的人可以玩玩看,只用標準庫而已
#include <string>
#include <fstream>
// 從外部取得字串
static std::string GetString()
{
std::ifstream input;
// in.txt 使用UTF8無BOM格式,檔尾有換行字元
input.open("in.txt",std::ifstream::in);
std::string str;
std::getline(input,str,'\n');
return str;
}
int main()
{
// 成功輸出成正確UTF8格式文件,因為VS沒機會動手腳
//std::string str = GetString();
// 輸出的文件總是big5格式,我改不了
std::string str = "abcd中文abc";
std::ofstream file;
file.open("log.txt");
file<<str<<std::endl;
return EXIT_SUCCESS;
}
※ 編輯: eye5002003 (118.167.51.47), 09/14/2017 12:33:00
推
09/14 12:45, , 19F
09/14 12:45, 19F
→
09/14 12:45, , 20F
09/14 12:45, 20F
→
09/14 12:47, , 21F
09/14 12:47, 21F
→
09/14 12:55, , 22F
09/14 12:55, 22F
/utf-8 /source-charset:utf-8 /execution-charset:utf-8 /validate-charset
這幾個全加進去也沒用,VS2010依然故我
你提供的連結看起來最像答案了,連這個也沒用
我可能還是乖乖的從外部讀取好了
也許這選項在2015是有用的,也許
※ 編輯: eye5002003 (118.167.51.47), 09/14/2017 13:21:30
推
09/14 13:46, , 23F
09/14 13:46, 23F
對啊,MinGW不會改成big5
只要能阻止VS修改,VS也是一樣輸出UTF8文件
目前看來想要好好跨平台使用Unicode的話只能這樣
1.總是使用L"str"這樣的寬字元字串,有必要再轉編碼(留意Linux下的wchar_t是32bit)
2.像我這樣從外部讀取
反正多語系程式設計上常常是將文字儲存在外部檔案(XML或是腳本之類的)
※ 編輯: eye5002003 (118.167.51.47), 09/14/2017 14:27:04
推
09/14 14:30, , 24F
09/14 14:30, 24F
→
09/14 14:32, , 25F
09/14 14:32, 25F
→
09/14 14:53, , 26F
09/14 14:53, 26F
※ 編輯: eye5002003 (118.167.51.47), 09/14/2017 15:18:28
※ 編輯: eye5002003 (118.167.51.47), 09/14/2017 15:24:03
推
09/14 15:53, , 27F
09/14 15:53, 27F
→
09/14 15:53, , 28F
09/14 15:53, 28F
→
09/14 16:09, , 29F
09/14 16:09, 29F
C_and_CPP 近期熱門文章
PTT數位生活區 即時熱門文章