ZC: Win7x64 + Qt551(x86) + vs2013(x86)
ZC: 問題:UTF-8 在源碼文件中有中文時,有時會報編譯錯誤:C2001 & C2143
分析:
--> 於是,需要將源碼文件 保存成“UTF-8 + BOM”格式
--> “UTF-8 + BOM”格式,自VS2005開始,字符串的編碼方式 會轉換成系統默認的編碼方式 不一定與源碼文件的編碼方式相同...
--> “UTF-8 + BOM”格式的源碼中的 中文字符串 需要做特殊處理
ZC: 處理方式:
(1)、u8前綴 ==> VS2015才開始支持
(2)、使用 相關函數,對字符串 進行轉換 (這也有 兩種方式:[A]、使用WindowsAPI函數進行轉換,[B]、使用Qt的函數進行轉換)
(3)、在文件開頭需要使用漢字的地方,一般是CPP文件的開始處,加上這句“#pragma execution_character_set("utf-8")”,這是告訴vs編譯器,咱們要使用UTF-8了
1、vs2010 error C2001: 常量中有換行符 (http://blog.csdn.net/bytxl/article/details/46046513)
在XCODE那邊寫的代碼,在window上編譯經常會出現
vs2010 error C2001: 常量中有換行符
原因:中文字符
非常奇怪的是只有部分中文會提示。
GOOGLE了下發現以下幾種解決方案:
I 不用中文 -_-
II 偶數中文 或 結尾加英文的符號,如"."
III 字符轉換 GBKToUTF8
參考:
http://www.cocoachina.com/bbs/read.php?tid=96304
http://blog.sina.com.cn/s/blog_7a25340e01011l4f.html
目前采用第二種方案,因為String將來肯定要移到配置文件里去的。如Android的string.xml
2013.6.25
原因: 非BOM的UTF-8格式
http://www.cnblogs.com/cocos2d-x/archive/2012/02/26/2368873.html
解決方案
中文放到string.xml里去
詳情參見 LabelTest.cpp 的 BMFontUnicode方法
[cpp] view plaincopy
CCDictionary *strings = CCDictionary::createWithContentsOfFile("fonts/strings.xml");
const char *chinese = ((CCString*)strings->objectForKey("chinese1"))->m_sString.c_str();
const char *japanese = ((CCString*)strings->objectForKey("japanese"))->m_sString.c_str();
const char *spanish = ((CCString*)strings->objectForKey("spanish"))->m_sString.c_str();
http://blog.csdn.net/xpwang168/article/details/8706810
1.1、cocos2d-x中文顯示問題 (http://www.cnblogs.com/cocos2d-x/archive/2012/02/26/2368873.html)
很高興你來到我的博客,同時也要感謝你對cocos2d-x引擎的支持。不過,既然你在這個時候來到這里,那八成是因為你遇到了麻煩——在你的cocos2d-x應用中,中文的顯示似乎不太正常。
雖然cocos2d-x是一個跨平台的2D游戲引擎,但是目前我只使用VC在Win32平台下學習她。如果你是在其他平台上做開發,那么這篇文章對你可能沒有太大幫助,我建議你閱讀cocos2d-x的代碼,找出問題的關鍵,從而定制一個可行的解決方案。
作為一名初學者,你必定像我一樣跟着教程將代碼敲進編輯器里,保存,編譯,運行。卻驚奇地發現中文字符串要么不顯示了,要么顯示成了亂碼。心里想着,天啊,什么地方出問題了。然后打開百度、谷歌,搜索“cocos2d-x 中文”。於是你找到了解決方案,要把文件保存為“無簽名的UTF-8”編碼。
按照上面的方法操作,編譯,運行,這時你已經可以看到中文字符顯示正常了。如果你還有別的什么重要的事情要做,沒有時間聽我在這里廢話,那么你現在就可以點擊窗口上的叉叉離開了。
。。。。。。
咳咳。。。
你還在這里?你還想聽聽為什么會這樣嗎?
額。。。好吧,那我就簡單說一下。以創建一個label為例,當我們使用
CCLabelTTF * CCLabelTTF::labelWithString(const char *label, const char *fontName, float fontSize)
來創建label的時候,實際上這里的const char *參數期望的是UTF-8編碼的字符串(你可以查看CCImage_win32.cpp中BitmapDC的drawText函數來印證我的說法),如果傳入一個非UTF-8編碼的字符串,那么創建的label就會顯示得不太正常。
注意,這里所說的傳入參數的編碼是指程序運行時傳入的字符串的編碼,而不是源文件保存的編碼。這實際上是一個編譯器相關的問題,具體情況你可以通過這篇文章了解一下。http://blog.csdn.net/darkdong/article/details/6067119
簡單來說,如果你使用2005/2008/2010版的VC做開發,希望將UTF-8編碼的字符串硬編碼到源代碼中,並且不使用轉義字符"\xE6\xB1\x89"這種缺乏可讀性的方案,那么你必須將文件保存為“無簽名的UTF-8”編碼。
然而在VC上使用“無簽名的UTF-8”編碼保存代碼文件是有毒副作用的。有興趣的朋友可以跟我一起做個實驗。
新建一個“Win32 控制台應用程序”,然后添加如下代碼:
1 #include "stdafx.h"
2
3 int _tmain(int argc, _TCHAR* argv[])
4 {
5 const char str[] = "退出";
6 return 0;
7 }
然后將文件保存為“無簽名的UTF-8”編碼,編譯。
我用的是Microsoft Visual C++ 2010 學習版,輸出:
1>------ 已啟動全部重新生成: 項目: utf-8-test, 配置: Debug Win32 ------
1> stdafx.cpp
1> utf-8-test.cpp
1>d:\projects\utf-8-test\utf-8-test.cpp : warning C4819: 該文件包含不能在當前代碼頁(936)中表示的字符。請將該文件保存為 Unicode 格式以防止數據丟失
1>d:\projects\utf-8-test\utf-8-test.cpp(8): error C2001: 常量中有換行符
1>d:\projects\utf-8-test\utf-8-test.cpp(9): error C2143: 語法錯誤 : 缺少“;”(在“return”的前面)
========== 全部重新生成: 成功 0 個,失敗 1 個,跳過 0 個 ==========
有個叫wva的人遇到過類似問題,他向微軟提交了此bug
http://connect.microsoft.com/VisualStudio/feedback/details/341454/compile-error-with-source-file-containing-utf8-strings-in-cjk-system-locale
根據Visual C++ Compiler Team員工的解釋:
The compiler when faced with a source file that does not have a BOM the compiler reads ahead a certain distance into the file to see if it can detect any Unicode characters - it specifically looks for UTF-16 and UTF-16BE - if it doesn't find either then it assumes that it has MBCS. I suspect that in this case that in this case it falls back to MBCS and this is what is causing the problem.
看見了吧,對於那些沒有BOM的文件設計就是這樣的。從語氣上看,他們編譯器小組也不打算修改設計。所以呢,在VC上使用“無簽名的UTF-8”編碼的文件,你就是在抱着一顆不定時炸彈玩耍。因為你永遠都不敢確定哪些詞能通過編譯,哪些不能!
如果要硬編碼字符串,即便是字符編碼轉換也不一定能幫不上你。一旦你為此增加了字符編碼轉換的代碼,那么也意味着可移植性降低了。因為這從根本上是編譯器決定的。
所以如果你想要在你的cocos2d-x應用里使用中文,那么最好將它們存放到外部資源文件中去,然后提供一套文本資源獲取接口。
或者你僅僅是想像我一樣快點兒開始cocos2d-x引擎的學習,那么暫時放棄中文吧,應該能省下不少時間。
2、Qt5與Qt4差別:在Qt5中QTextCodec中的setCodecForTr等消失了 (http://blog.sina.com.cn/s/blog_bb3b5c230102uxen.html)
本文轉載轉載自:http://blog.csdn.net/dbzhang800/article/details/7325698
該片博主痛批了那些濫用QTextCodec,雖然我還是不懂在看霍亞飛大俠寫的基於Qt4.7.2和Qt Creator2.1.0版本《Qt Creator快速入門》中,霍大俠開篇就提醒我,國際化很重要,有中文要轉碼在主函數中要加上:
QTextCodec::setCodecForTr(QTextCodec::codecForLocal());
QTextCodec::setCodecForTr(QTextCodec::codecRForName("GB18030"));
QTextCodec::setCodecForCString(QTextCodec::codecForLocal());
我也不懂,Qt5編譯不了,我就直接屏蔽了!
但是在編譯書中源代碼是就很頭疼,很多錯誤!
下面是本人總結的由Qt4轉到Qt5的一些解決方法
原來是Qt4與Qt5版本有很大的差別,首先使用了widget的你在都要在.pro項目文件中加入一句:
QT += widgets
並且main.cpp的頭文件
#include 要改成 #include
然后是QTextCodec::setCodecForTr( )函數沒有了,沒有我就刪掉你!
差不多了,基本上的程序都能運行。
但到后面界面出現中文就亂碼,搞了半天也沒懂!
找到這篇博文后我以為找到福星,能夠拯救我!
但還不夠,我太菜了,這樣高大上的文章我看不懂大俠啊!
經過摸索后,修改了下大俠的博客,讓我們這些菜鳥能夠直接使用,直接解決問題!
修改原文如下!
在Qt4中,國內很多新手都喜歡——不分青紅皂白地使用如下3行代碼
QTextCodec::setCodecForTr(...) QTextCodec::setCodecForCStrings(...) QTextCodec::setCodecForLocale(...)
盡管之前零零散散寫過一點這方面的內容,比如
但是,敢死隊員還是一批一批的 ... 讓人少多有些無奈
症結?
在國內,之所以用很多人用這3行代碼,是因為他們在源代碼的const char*這種窄字符串中使用了中文。
然后,發現。不對啊,咋全是亂碼呢?於是上網搜索,發現其他人用的這3行代碼
於是,加上試試。發現:在自己的當前環境下(固定系統、固定地區語言設置、固定編譯環境)還真的沒有亂碼了。
於是乎?完全不考慮那3行代碼的作用了,反正自己能用就行了,管它什么副作用呢!!
Qt5
在Qt5中,這個問題終於不復存在了,因為
這兩個函數
QTextCodec::setCodecForTr(...) QTextCodec::setCodecForCStrings(...)
被直接去掉了。
這樣一來,受影響的直接是如下代碼了:
QString s1 = "我是中文"; QString s2("我是中文"); QString s3 = QObject::tr("我是中文")
好消息/壞消息?
-
壞消息:
現在Qt5中盡管去掉了setCodecXXX這兩個函數,但是默認編碼還是latin1。如果你要想使用
"我是中文"
這樣的字符串,必須自己使用QTextCodec或這QString::fromXXX 這種東西進行轉換
這里擴展一下如何使用QTextCodec或這QString::fromXXX 這種東西進行轉換
1、QTextCodec *codec = QTextCodec::codecForName(
"GB2312"
);//或者是GB18030
label->setText(codec->toUnicode(
"我是中文"
));
2、 label->setText(QString::fromLocal8Bit("我是中文"
));
關於文字編碼方式、編碼表、編碼器等相關內容可以Google或者百度去了解。
-
好消息 是:
Qt5發布之時,默認將會是utf8編碼,完全可以將你從Qt編碼問題解放出來。
-
壞消息,如果使用的是 MSVC2005/2008/2010,可能無法使用utf8編碼,於是
下面的代碼
QString s1 = "我是中文"; QString s2("我是中文"); QString s3 = QObject::tr("我是中文")
將不會工作。
- 因為從MSVC2005起,你無法給編譯器設置字符串要使用的編碼。盡管2003之前,也無法設置,但是它會遵循源碼文件的編碼。而2005就自作聰明了,即使你源碼文件保存成不帶BOM的utf8,它都會試圖幫你轉換一下。
-
好消息是什么呢?
如果你在Windows下,且使用的是MinGW,那么只要你將源碼文件保存成utf8,前面的代碼將直接可以工作(無須其他設置)
如果你在其他平台了,那么應該都默認是utf8文件。同樣無須進行設置。
-
好消息
如果你的編譯器支持C++11,那么,你可以直接使用
QString s = u8"我是中文";
-
壞消息
主流編譯器還都不怎么支持C++11
參考
3、QT5.6.0+vs2015源碼中含有中文的解決辦法 http://www.qtcn.org/bbs/read-htm-tid-60825.html
默認是UTF-8無BOM
然后編譯的時候,漢字的數量偶數就可以,奇數不行,編譯都不過
用了GBK后可以編輯,但顯示不正常
后來用的這種方法:
1、將文件編碼轉為UTF-8有BOM的,這里推薦工具editplus,可以批量轉化
2、在文件開頭需要使用漢字的地方,一般是CPP文件的開始處,加上這句“#pragma execution_character_set("utf-8")”,
這是告訴vs編譯器,咱們要使用UTF-8了
4、
5、