vs 中如何解决 C++的“常量中有换行符”

2021-11-27 11:19:47 +08:00
 amiwrong123

环境:Windows 上使用 vs

总是遇到那种定义一个中文字符串std::string = "你好";(不一定是这段中文),然后 vs 就编译报错“常量中有换行符”。

我看了网上的文章,大概意思就是会收到这三个的影响:

我理解一下,就是:

不知道我上面的流程理解对不对?(我觉得流程理解清楚,这个问题也就好解决了)

而且想再问一下,解决“常量中有换行符”的最佳方案:

3561 次点击
所在节点    程序员
28 条回复
vinmkzr
2021-11-27 11:33:37 +08:00
我对 C 比较熟悉,你对字符组的理解按 C 来说是正确的;
在 linux 上写代码用 gcc 编译的话,三个字符组默认都是 utf-8 ;
我碰到过最差的情况是,项目里面有 EUC-JP ,shif-jis 几种日文编码混合,最后的解决办法是用 uchardet+iconv 写脚本全转换到 utf-8
vanton
2021-11-27 11:43:07 +08:00
系统改成 utf-8, 整个项目也用 utf-8
mangohaoming
2021-11-27 11:52:30 +08:00
vs 中包含中文的文件最好使用 utf-8-withBom 的编码格式
amiwrong123
2021-11-27 11:55:00 +08:00
https://www.cnblogs.com/jiangxueqiao/p/7464408.html#!comments

这篇文章里提到:
vs 编译器判断源文件编码类型的步骤为:
1. 若文件开始处有 BOM(EF BB BF),则判定为 UTF-8 编码;
2. 若没有 BOM ,则试图从文件的前 8 个字节来判断文件是否像 UTF-16 编码,如果像,则就判断为 UTF-16 编码。
3. 如果既没 BOM ,也不是 UTF-16 编码,则使用系统当前的代码页(简体中文操作系统为 CP936 )。

我理解是这样的:
如果没有设置 /source-charset ,那么会执行这三步,根据这三步来得到最终的 /source-charset 。
如果已经设置了 /source-charset ,那么不会执行这三个步骤,直接使用 设置的 /source-charset 。

有没有经常用 vs 的老哥,是不是这样呀😂
amiwrong123
2021-11-27 11:59:25 +08:00
@mangohaoming #3
老哥你看看我 4 楼的问题呗

这篇文章也是说,最好 utf-8-withBom 。但我的 c++代码也需要在 linux 上编译,就得跨平台。

而且这篇文章说,最好使用 wchar_t 。我有点不理解。关键这个类型大家感觉也不常用啊,到时候和别人代码一对接,好多地方要改,还可能出错。。
koebehshian
2021-11-27 13:03:29 +08:00
源代码中不要有中文,字符串这种 UI 的东西放到配置文件中,配置文件统一用 utf8
yolee599
2021-11-27 13:21:08 +08:00
源码请统一使用 utf-8 编码,不要贪图一时方便使用 gb2312 ,后面你会遇到各种各样问题
wudicgi
2021-11-27 13:28:45 +08:00
MSVC 的话,编译器的命令行参数中,手动加一项 /utf-8
https://docs.microsoft.com/en-us/cpp/build/reference/utf-8-set-source-and-executable-character-sets-to-utf-8?view=msvc-170

我是倾向于直接加编译参数,而不是所有文件加上 BOM 头
mangohaoming
2021-11-27 13:40:49 +08:00
@amiwrong123 linux 编译 utf-8-withBom 会存在问题吗,我印象中没碰到什么奇怪问题。我用 mingw 编译是 ok 的,我 vscode 的默认编码一直是 utf-8-withBom 的编码。
amiwrong123
2021-11-27 13:41:54 +08:00
@koebehshian #6
他的代码 是 那种处理中文文本的一种程序(类似,NLU )。总之,肯定会有 中文字符串常量。这没法阿
amiwrong123
2021-11-27 13:47:50 +08:00
@yolee599 #7
那要不要 withBom 呢?
因为 vs 编译,最好是 withBom 的
koebehshian
2021-11-27 13:59:06 +08:00
@amiwrong123 他做 NLU 的,居然对中文编码都不了解
skinny
2021-11-27 14:00:55 +08:00
我虽然没有遇到过,但是千万别用 UTF8 with BOM ,坑太多了,之前写 PowerShell 脚本,5.1 及以下版本以 UTF8 编码输出的文本就是带 BOM 的,遇到二进制处理或传给别的外部命令处理时就容易出错,上次也是查了好一会儿才发现问题。
amiwrong123
2021-11-27 14:08:44 +08:00
@wudicgi #8
我也这么觉得。老哥你看看我 4 楼的问题呢,那篇文章把我弄懵了,我理解:
如果已经设置了 /source-charset ,那么不会执行那三个步骤,直接使用 设置的 /source-charset 。对吗😂
amiwrong123
2021-11-27 14:13:31 +08:00
@mangohaoming #9
是吗,我就是怕 withBom 的 有问题,所以才来发帖😂
amiwrong123
2021-11-27 14:16:00 +08:00
@koebehshian #12
哎,我也不知道为啥他的源文件编码格式都是 gb2312😂
我只是负责集成包装成接口给上层使用,而且之前他好像还说过,不要改他的源文件的编码格式,不然可能会出问题😂
mangohaoming
2021-11-27 14:27:16 +08:00
@amiwrong123 看这个讨论,至少 gcc 是正常支持带 bom 的 https://www.v2ex.com/t/403068
wudicgi
2021-11-27 15:19:20 +08:00
@amiwrong123 那篇文章我觉得没啥参考价值,实际上不用搞这么复杂

实践中,项目设为 Unicode 字符集这是毫无疑问的
为了兼容性我会 #include <tchar.h>, 然后用 TCHAR 和 _tprintf() 之类符号代替 char/wchar_t, printf()
同时也还是为了兼容性,我不会用 BOM 头,而是把源文件的字符集统一成 UTF-8, 加编译参数直接指定

我之前在 V2EX 上发过的这个项目就是这么做的
https://github.com/wudicgi/SpleeterMsvcExe
wudicgi
2021-11-27 15:29:57 +08:00
@amiwrong123 或者你在 VS 中为他的那些文件设置自己的 /source-charset 和 /execution-charset 参数

/utf-8 等价于 /source-charset:utf-8 /execution-charset:utf-8
可以给他的那些源文件加上 /source-charset:gb2312 编译参数

但说实话,这样处理除了不用动他的那些文件外,和提前把那些文件都转为 UTF-8 编码没什么区别
ipwx
2021-11-27 16:20:09 +08:00
utf-8 编码是截断安全的,它保证了多字节序列不可能出现换行符作为某个中文的一部分。

gb2312 不是截断安全的。

所以要用 utf-8

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/818321

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX