用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控制台的情况下,通过调用_setmode
将stdout
的转换模式显式设置为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; }