【发布时间】:2013-03-09 19:57:19
【问题描述】:
在这样的语句中,两者都以相同的编码(UTF-8)输入到源代码中,并且语言环境设置正确,它们之间有什么实际区别吗?
printf("ο Δικαιοπολις εν αγρω εστιν\n");
printf("%ls", L"ο Δικαιοπολις εν αγρω εστιν\n");
因此,在输出时是否有任何理由偏爱其中一个?我想第二个的表现要差一些,但它比多字节文字有什么优势(或劣势)吗?
编辑:这些字符串打印没有问题。但我没有使用宽字符串函数,因为我也希望能够使用printf 等。所以问题是这些打印方式有什么不同(鉴于上述情况),如果是这样,第二种有什么优势吗?
EDIT2:按照下面的 cmets,我现在知道这个程序可以工作——我认为这是不可能的:
int main()
{
setlocale(LC_ALL, "");
wprintf(L"ο Δικαιοπολις εν αγρω εστιν\n"); // wide output
freopen(NULL, "w", stdout); // lets me switch
printf("ο Δικαιοπολις εν αγρω εστιν\n"); // byte output
}
EDIT3:我通过查看这两种类型的情况做了一些进一步的研究。取一个更简单的字符串:
wchar_t *wides = L"£100 π";
char *mbs = "£100 π";
编译器正在生成不同的代码。宽字符串是:
.string "\243"
.string ""
.string ""
.string "1"
.string ""
.string ""
.string "0"
.string ""
.string ""
.string "0"
.string ""
.string ""
.string " "
.string ""
.string ""
.string "\300\003"
.string ""
.string ""
.string ""
.string ""
.string ""
而第二个是:
.string "\302\243100 \317\200"
看看 Unicode 编码,第二种是纯 UTF-8。宽字符表示是 UTF-32。我意识到这将取决于实现。
所以也许文字的宽字符表示更便携?我的系统不会直接打印 UTF-16/UTF-32 编码,所以会自动转换成 UTF-8 输出。
【问题讨论】:
-
你说这两个例子都是用 UTF-8 输入的。在第二个示例行中,如果该文本实际上是 UTF-8 而不是宽编码,那么您可能不应该有 L 前缀,因此您只需使用
%s而不是%ls。或者我仍然误解了这个问题。 -
@AdrianMcCarthy - 源代码中的两个字符串都是 UTF-8,是的。但是字符串文字总是多字节的——“字符串文字是用双引号括起来的零个或多个多字节字符的序列,如“xyz”。宽字符串文字是相同的,除了以字母 L 为前缀。 "从标准。
-
AFAIR,任何不在基本源字符集中的字符(它是 US-ASCII-7 的 子集)都会调用实现定义的行为,即这里讨论的所有内容都是有效的取决于使用的编译器。如果你真的想安全地玩它(和便携),你将不得不求助于 \u... 和 \U...
-
很可能在实施领域。我想要做的是一直切换到宽字符表示,但坚持使用常规的 stdio 函数进行输出,以免破坏与所有期望它们工作的东西的兼容性。我真的只是想知道我是否应该单独使用多字节文字(如上所述),或者是否有理由使用宽文字。这很难解释,而且我做得不是很好!
-
utf8everywhere.org 几乎说服了不鼓励使用 L"",尤其是在 Windows 平台上。
标签: c unicode utf-8 printf multibyte