2009-11-02 39 views
12

我想创建与编码处理的一些样本程序,具体我想 使用宽字符串等:规格在MSVC++源字符集编码的,像GCC“-finput-字符集=字符集”

wstring a=L"grüßen"; 
wstring b=L"שלום עולם!"; 
wstring c=L"中文"; 

因为这些都是示例程序。

这对于将源代码视为UTF-8编码文本的gcc来说绝对是微不足道的。 但是,直接编译在MSVC下不起作用。我知道我可以使用转义序列将它们编码为 ,但我宁愿将它们保留为可读文本。

是否有任何选项可以指定为“cl”的命令行开关,以便 使这项工作成为可能? 有有任何命令行开关一样gcc'c -finput-charset

感谢,

如果没有你怎么会建议让文字自然的用户?

注意:将BOM添加到UTF-8文件不是一个选项,因为它不会被其他编译器编译。

注2:我需要它在MSVC版本工作> = 9 == VS 2008

真正的答案:有编码组合无解

+3

这真是令人惊讶的MSVC++没有这样的编译器的选项。真是太遗憾了...... – 2011-03-13 22:37:02

+0

我问你这个问题的意思是*源文件** charset *的规范。 *源字符集*是用于编译器内部使用的实现定义字符集的标准中的术语。 – 2011-03-14 20:20:08

+1

@PiotrDobrogost有人猜测为什么微软没有通过本机支持编译和SDK的UTF-8来满足世界其他地区的需求,并且在必须国际化Windows应用程序的程序员的生活中增加了如此多的低效率,麻烦,混乱和痛苦在UTF-8世界。但我有一个猜测;它被称为*官僚主义*和*利润动机*超过关心或质量的关注。 – 2015-01-10 02:16:33

回答

7

对于那些订阅座右铭“比从不迟到”更好的人来说,Visual Studio 2015(编译器19版)现在支持这一点。

新的/source-charset命令行开关允许您指定用于解释源文件的字符集编码。它采用单个参数,其可以是所述IANA或ISO字符集名:

/source-charset:utf-8 

或一个特定的代码页的十进制标识符(由点之前):

/source-charset:.65001 

官方文档是here,在Visual C++团队博客上也有a detailed article describing these new options

还有一个补充/execution-charset switch,其工作方式完全相同,但控制可执行文件中生成的字符和字符串的范围有多窄。最后,有一个快捷开关/utf-8,它设置了/source-charset:utf-8/execution-charset:utf-8

这些命令行选项不相容与老#pragma setlocale#pragma execution-character-set指令,它们适用于全球所有的源文件。

对于停留在旧版本编译器上的用户,最好的选择仍然是将源文件保存为带有BOM的UTF-8(如其他答案中所建议的,IDE可以在保存时执行此操作)。编译器会自动检测到这一点,并适当地运行。同样,GCC也会在源文件开始时接受BOM而不会窒息而死,这使得这种方法在功能上是可移植的。

5

打开File->Advances Save Options... 选择Unicode(UTF-8 with signature) - Codepage 65001。编译器将自动使用选定的编码。


根据微软的答案here

如果你想非ASCII字符

那么“官方”和便携的方式让他们是使用\ u(或\ U)十六进制编码(这是,我同意,只是简单丑陋和容易出错)。

编译器遇到没有BOM的源文件时,会提前读取文件中的一定距离,看它是否能检测到任何Unicode字符 - 它专门查找UTF-16和UTF-16BE - 如果它没有找到,那么它假定它有MBCS。我怀疑在这种情况下,它会回落到MBCS,这是导致问题的原因。

明确是最好的,所以虽然我知道这不是一个完美的解决方案我建议使用BOM

Jonathan Caves
Visual C++编译器团队。


良好的解决方案将是把文本字符串中的资源文件。这是方便和便携的方式。您可以使用本地化库(例如gettext)来管理翻译。

+0

该文件已经以UTF-8编码 – Artyom 2009-11-02 14:34:32

+0

编译器自动转换文件中的字符串常量,因此字符串将使用UCS2编码存储在EXE中。 – 2009-11-02 15:20:34

+0

好的,我明白了,你建议手动在UTF-8上添加“BOM”标记,它确实有效,但问题在于gcc和其他编译器无法处理没有意义的BOM。 – Artyom 2009-11-02 19:05:13

1

对于VS可以使用:

#pragma setlocale("[locale-string]") 

的区域设置的默认ANSI代码页将被用作文件编码。

但是,在代码中硬编码任何用户可见的字符串通常是一个坏主意。 将它们存储在某种资源中。很好的本地化,易于拼写检查和更新等。

+0

“但是,在代码中硬编码任何用户可见的字符串通常是一个糟糕的主意”我知道,但这主要是用于这样的事例,这些事情对用户来说很重要,以便看到什么是真正的发生。但是如何在locale字符串中指定UTF-8字符集呢?据我所知,Windows不支持UTF-8编码的语言环境。 – Artyom 2009-11-11 09:37:53

+0

短暂测试后,MSVC 2005未​​能接受'setlocale(“。65001”)'即UTF-8代码页。 – Artyom 2009-11-11 09:52:54

+0

65001是一个代码页,编译指示需要一个语言环境。 没有使用UTF-8作为代码页的区域设置。 如果你只需要它在VS中工作,你可以将它保存为UTF-16 (从记事本“另存为”和选择编码“Unicode”) 否则唯一便携的方法就是将其转义为Sherwood Hu建议。喜欢与否,这是唯一的方法。 而正确的方法是不在你的c文件中硬编码:-) – 2009-11-15 08:38:00

2

恕我直言,所有的C++源文件应严格的ASCII。如果编辑器支持,评论可以用UTF-8编写。
这使得代码可以在平台,编辑器和源代码控制系统之间移植。

您可以使用\u插入Unicode字符转换为一个宽字符串:

std::wstring str = L"\u20AC123,00"; //€123,00 
+5

Thants我究竟**不想**想做什么 – Artyom 2009-11-12 20:28:36

2

我们使用的流程:将文件保存为UTF8-与BOM,共享Linux和Windows之间的相同的源,对于Linux:预处理编译命令中的源文件为了删除BOM,在中间非BOM文件上运行g ++。