环境:Windows 上使用 vs
总是遇到那种定义一个中文字符串std::string = "你好";
(不一定是这段中文),然后 vs 就编译报错“常量中有换行符”。
我看了网上的文章,大概意思就是会收到这三个的影响:
我理解一下,就是:
不知道我上面的流程理解对不对?(我觉得流程理解清楚,这个问题也就好解决了)
而且想再问一下,解决“常量中有换行符”的最佳方案:
1
vinmkzr 2021-11-27 11:33:37 +08:00
我对 C 比较熟悉,你对字符组的理解按 C 来说是正确的;
在 linux 上写代码用 gcc 编译的话,三个字符组默认都是 utf-8 ; 我碰到过最差的情况是,项目里面有 EUC-JP ,shif-jis 几种日文编码混合,最后的解决办法是用 uchardet+iconv 写脚本全转换到 utf-8 |
2
vanton 2021-11-27 11:43:07 +08:00
系统改成 utf-8, 整个项目也用 utf-8
|
3
mangohaoming 2021-11-27 11:52:30 +08:00
vs 中包含中文的文件最好使用 utf-8-withBom 的编码格式
|
4
amiwrong123 OP 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 的老哥,是不是这样呀😂 |
5
amiwrong123 OP @mangohaoming #3
老哥你看看我 4 楼的问题呗 这篇文章也是说,最好 utf-8-withBom 。但我的 c++代码也需要在 linux 上编译,就得跨平台。 而且这篇文章说,最好使用 wchar_t 。我有点不理解。关键这个类型大家感觉也不常用啊,到时候和别人代码一对接,好多地方要改,还可能出错。。 |
6
koebehshian 2021-11-27 13:03:29 +08:00 1
源代码中不要有中文,字符串这种 UI 的东西放到配置文件中,配置文件统一用 utf8
|
7
yolee599 2021-11-27 13:21:08 +08:00 via Android
源码请统一使用 utf-8 编码,不要贪图一时方便使用 gb2312 ,后面你会遇到各种各样问题
|
8
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 头 |
9
mangohaoming 2021-11-27 13:40:49 +08:00
@amiwrong123 linux 编译 utf-8-withBom 会存在问题吗,我印象中没碰到什么奇怪问题。我用 mingw 编译是 ok 的,我 vscode 的默认编码一直是 utf-8-withBom 的编码。
|
10
amiwrong123 OP @koebehshian #6
他的代码 是 那种处理中文文本的一种程序(类似,NLU )。总之,肯定会有 中文字符串常量。这没法阿 |
11
amiwrong123 OP |
12
koebehshian 2021-11-27 13:59:06 +08:00
@amiwrong123 他做 NLU 的,居然对中文编码都不了解
|
13
skinny 2021-11-27 14:00:55 +08:00
我虽然没有遇到过,但是千万别用 UTF8 with BOM ,坑太多了,之前写 PowerShell 脚本,5.1 及以下版本以 UTF8 编码输出的文本就是带 BOM 的,遇到二进制处理或传给别的外部命令处理时就容易出错,上次也是查了好一会儿才发现问题。
|
14
amiwrong123 OP @wudicgi #8
我也这么觉得。老哥你看看我 4 楼的问题呢,那篇文章把我弄懵了,我理解: 如果已经设置了 /source-charset ,那么不会执行那三个步骤,直接使用 设置的 /source-charset 。对吗😂 |
15
amiwrong123 OP @mangohaoming #9
是吗,我就是怕 withBom 的 有问题,所以才来发帖😂 |
16
amiwrong123 OP |
17
mangohaoming 2021-11-27 14:27:16 +08:00
@amiwrong123 看这个讨论,至少 gcc 是正常支持带 bom 的 https://www.v2ex.com/t/403068
|
18
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 |
19
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 编码没什么区别 |
20
ipwx 2021-11-27 16:20:09 +08:00
utf-8 编码是截断安全的,它保证了多字节序列不可能出现换行符作为某个中文的一部分。
gb2312 不是截断安全的。 所以要用 utf-8 |
21
nightwitch 2021-11-27 16:41:08 +08:00
全部用 utf-8 with bom,msvc 开 /utf-8 的标志。
远离 wchar 那一坨 |
22
ipwx 2021-11-27 16:53:30 +08:00
所以其实 Qt 的标准解决方案挺香。源代码都是英文,但用 tr(...) 函数包起来。这个函数负责在运行时根据语言包资源文件查表。。。这样就可以做到源代码没有多字节字符了,哪里都不会出问题。
|
23
ipwx 2021-11-27 16:53:53 +08:00
另外 QString 内存中是 UTF-16 。。。总之就挺香。
|
24
lonewolfakela 2021-11-27 17:26:40 +08:00
vs 的话,给编译器加 /utf-8 参数,然后所有源文件用 utf8 without bom 存,再在项目根目录加一个.editorconfig 文件,里面写上
[*.{c,cpp,cc,cxx,h,hpp,ixx}] charset = utf-8 这样比较好。 |
25
3dwelcome 2021-11-27 18:07:02 +08:00
我也遇到楼主这种中文编码问题,只在某些特定平台,特定版本 clang 编译出问题。
gcc 和 vc 倒是一点问题都没有。 最后也没找到很直接的解决办法,写了一个源代码预处理工具,实时转换 utf8 编码。 |
26
ysc3839 2021-11-27 18:34:27 +08:00 via Android
我个人目前是编译参数加上 /utf-8 ,然后源代码全都用 UTF-8 without BOM 存,同时在 manifest 里面声明 active codepage 为 UTF-8 ( https://docs.microsoft.com/en-us/windows/apps/design/globalizing/use-utf8-code-page ),代码中优先使用 UTF-16 。
@ipwx Qt 的那个字符串我感觉有点尴尬,默认情况下它是 UTF-8 的字符串字面量,运行时要分配新内存解码为 UTF-16 ,如果想直接存成静态 UTF-16 ,需要包个宏,很影响代码观感。 |
27
whi147 2021-11-28 10:47:25 +08:00 via iPhone
我的操作是包一层翻译器,从外部读取字符串。代码内部都是同一编码
|
28
macha 2021-11-30 09:27:30 +08:00
@amiwrong123 因为他在源码里面写了中文字符,我这边都强制大家写英文注释。vs 对中文支持不太好。
|