用printf打印UTF-8string与多字节string文字

在像这样的语句中,两者都以相同的编码(UTF-8)input到源代码中,并且语言环境设置正确,它们之间是否有实际区别?

printf("ο Δικαιοπολις εν αγρω εστιν\n"); printf("%ls", L"ο Δικαιοπολις εν αγρω εστιν\n"); 

因此,在做输出时,是否有理由相对于另一个? 我想第二个performance会更糟,但是它在多字节文字上有什么优势(或缺点)吗?

编辑:这些string打印没有问题。 但是我没有使用宽string函数,因为我希望能够使用printf等。 所以问题在于这些印刷方式是否与以上所述情况不符?如果是这样,第二种方式有什么优势?

编辑2:下面的评论,我现在知道这个程序的作品 – 我认为是不可能的:

 int main() { setlocale(LC_ALL, ""); wprintf(L"ο Δικαιοπολις εν αγρω εστιν\n"); // wide output freopen(NULL, "w", stdout); // lets me switch printf("ο Δικαιοπολις εν αγρω εστιν\n"); // byte output } 

编辑3 :我已经做了一些进一步的研究,看看这两种types正在发生什么。 采取更简单的string:

 wchar_t *wides = L"£100 π"; char *mbs = "£100 π"; 

编译器正在生成不同的代码。 宽string是:

 .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输出。

 printf("ο Δικαιοπολις εν αγρω εστιν\n"); 

打印string文字( const char* ,特殊字符表示为多字节字符)。 尽pipe您可能会看到正确的输出,但在处理这些非ASCII字符时,可能会遇到其他问题。 例如:

 char str[] = "αγρω"; printf("%d %d\n", sizeof(str), strlen(str)); 

输出9 8 ,因为这些特殊字符中的每一个都由2个char表示。

在使用L前缀时,由宽字符( const wchar_t* )和%ls格式说明符组成的字面量const wchar_t*这些宽字符转换为多字节字符 (UTF-8)。 请注意,在这种情况下,区域设置应适当设置,否则此转换可能导致输出无效:

 #include <stdio.h> #include <wchar.h> #include <locale.h> int main(void) { setlocale(LC_ALL, ""); printf("%ls", L"ο Δικαιοπολις εν αγρω εστιν"); return 0; } 

但是在使用宽字符时,有些事情会变得更加复杂,其他的事情可能会变得更简单,更直接。 例如:

 wchar_t str[] = L"αγρω"; printf("%d %d", sizeof(str) / sizeof(wchar_t), wcslen(str)); 

会输出5 4正如人们所期望的那样。

一旦决定使用宽string,可以使用wprintf直接打印宽字符 。 在这里也值得注意的是,在Windows控制台的情况下,通过调用_setmodestdout的转换模式显式设置为Unicode模式_setmode

 #include <stdio.h> #include <wchar.h> #include <io.h> #include <fcntl.h> #ifndef _O_U16TEXT #define _O_U16TEXT 0x20000 #endif int main() { _setmode(_fileno(stdout), _O_U16TEXT); wprintf(L"%s\n", L"ο Δικαιοπολις εν αγρω εστιν"); return 0; }