• QQ
  • nahooten@sina.com
  • 常州市九洲新世界花苑15-2

技术天地

Qt5_vs2013_error_C2001: 常量中有换行符

原创内容,转载请注明原文网址:http://homeqin.cn/a/wenzhangboke/jishutiandi/2019/1110/695.html

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: 常量中有换行符 
 
复制代码
在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花样
 
办理方案
中文放到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();  
 
复制代码
  1.1、cocos2d-x中文表现题目 
 
很高兴你到达我的博客,同时也要谢谢你对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就会表现得不太平常。
留意,这里所说的传入参数的编码是指程序运转时传入的字符串的编码,而不是源文件留存的编码。这现实上是一个编译器关联的题目,详细情况你能够经历这篇文章打听一下。
简单来说,要是你使用2005/2008/2010版的VC做开辟,有望将UTF-8编码的字符串硬编码到源代码中,而且不使用转义字符"\xE6\xB1\x89"这种短缺可读性的方案,辣么你必需将文件留存为“无署名的UTF-8”编码。
 
然而在VC上使用“无署名的UTF-8”编码留存代码文件是有毒反用途的。有乐趣的身边的人能够跟我一起做个试验。
新建一个“Win32 掌握台运用程序”,然后增加以下代码:
 
复制代码
复制代码
1 #include "stdafx.h"
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)
 
 
该片博主痛批了那些乱用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(...)
只管以前零零星散写过一点这方面的内容,好比
 
QString 与中文题目
 
Qt中translate、tr关系 与中文题目
 
Qt国外化(源码含中文时)的点滴说明
 
但是,敢死队员或是一批一批的 ... 让人少多有些无奈
 
症结?
在国内,之以是用许多人用这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
 
参考
http://codereview.qt-project.org/#change,14999
 
http://codereview.qt-project.org/#change,14626
 
 
 
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、
 
 
 
分类: 字符集(编码)
 

上篇:上一篇:基于MySQL Connector/C++的MySQL操作(Pool)
下篇:下一篇:c++ map应用(增删查改遍历)