Qt5_vs2013_error_C2001: 常量中有换行符__资料

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、

 

posted @ 2016-11-16 09:45  CppSkill  阅读(8095)  评论(1编辑  收藏  举报