※ 引述《allssddaa (屌炸天)》之铭言:
→ uranusjr: 啊我知道是怎么回事了, 对你的档案是 UTF8 没错但 cl 吃 07/05 15:39
→ uranusjr: 不了, 因为默认的编译模式是 UTF-16 (印象中) 07/05 15:40
→ uranusjr: 在 .pro 档加上 QMAKE_CXXFLAGS += /utf-8 不知道能不能 07/05 15:41
: 喔喔喔解决了耶
: 非常感谢
: 在.pro加那段就可以编译而且没有乱码
: 请问"CL吃不了因为默认是UTF-16"是什么意思呢?
: 加上那一行又是做了什么改变呢?
发现我讲得七零八落, 不如写一篇完整的
VC++ 编译器 (cl.exe) 看到一个原始码档案时会试着解读它的编码
默认状况下有两种可能: local codepage 和 UTF-16
判别的方法是, cl.exe 会检查档案开头有没有 BOM [1]
如果有就当成 UTF-16, 否则使用 local codepage 解码
你的 local codepage 视作业系统的设定而定
如果你用繁体中文, 那么通常就是 CP950, 一种相容 Big 5 的编码
这和 UTF-8 在 ASCII 范围内相容 [2], 所以如果只用 ASCII 字符, 程式就能正常编译
但只要用了其它字符就可能出错 (只是可能, 所以很靠北 XD)
那如果你要用非 ASCII 字符, 解法有两个
一是把源码存成 UTF-16——绝大多数状况是个坏主意, 这是另一个议题
另一个就是明确告诉 cl.exe 你要用的编码, 叫它不要猜
/utf-8 是一个 compiler flag, 用来设定源档与执行档的编码格式 [3]
它相当于 /source-charset:utf-8 /execution-charset:utf-8
对 Qt 而言 execution charset 没有意义 (除非你另外用了 Windows API)
所以其实在这里把它换成 /source-charset:utf-8 也行
QMAKE_CXXFLAGS 是一个 qmake directive
它用来告诉 qmake 要把额外参数喂给编译器
如果你去比对加这个参数前后产生出来的 Makefile
就会看到这个 directive 的内容辗转被丢到 cl.exe 的后面当参数
所以这样就可以指定你的源码编码, 解决这个问题
我自己是学乖了, 现在程式码里只放 ASCII
中文通常都用翻译档 [4] 来给
如果真的不得已, 就用 QString::fromUtf8("\xe4\xb8\xad\xe6\x96\x87") 这样
不然 VC++ 神难搞, 用 compiler flag 要跨平台也很麻烦
或者如果你不介意, Qt 搭配 MinGW 用起来会更顺
[1]: https://zh.wikipedia.org/zh-tw/字节顺序记号
[2]: 其实是和 Western-1 在 0-255 码位相容, 而 UTF-8 是 Western-1 的超集
[3]: https://msdn.microsoft.com/en-us/library/mt708821.aspx
[4]: http://doc.qt.io/qt-5/i18n-source-translation.html