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编码的字符串硬编码到源代码中,并且不使用转义字符"xE6xB1x89"这种缺乏可读性的方案,那么你必须将文件保存为“无签名的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:projectsutf-8-testutf-8-test.cpp : warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
1>d:projectsutf-8-testutf-8-test.cpp(8): error C2001: 常量中有换行符
1>d:projectsutf-8-testutf-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、