单个C代码中的printf和wprintf

时间:2011-12-30 16:28:15

标签: c gcc internationalization

在代码中一起使用printfwprintf函数时遇到问题。如果首先打印常规字符串,则wprintf不起作用。如果我先使用wprintf,则printf无效。

#include <stdio.h>
#include <wchar.h>
#include <stdlib.h>
#include <locale.h>

int main() 
{
    setlocale(LC_ALL,"");

    printf("No printing!\n");
    wprintf(L"Printing!\n");
    wprintf(L"Wide char\n");
    printf("ASCII\n");
    return 0;
}

输出:

No printing!
ASCII

虽然

#include <stdio.h>
#include <wchar.h>
#include <stdlib.h>
#include <locale.h>

int main() 
{
    setlocale(LC_ALL,"");

    wprintf(L"Printing!\n");
    printf("No printing!\n");
    wprintf(L"Wide char\n");
    printf("ASCII\n");
    return 0;
}

输出:

Printing!
Wide char

我在64位Linux 3.0上使用gcc(GCC)4.6.1 20110819和glibc 2.14。

2 个答案:

答案 0 :(得分:16)

这是可以预料的;您的代码正在调用未定义的行为。根据C标准,每个FILE流都与它相关联的“方向”(“字节”或“宽”),它由对其执行的第一个操作设置,并且可以使用{{1}进行检查。调用任何方向与流的方向冲突的函数会导致未定义的行为。

答案 1 :(得分:2)

补充R ..接受的答案:

虽然很少这样做,但检查printf / wprintf的返回代码会更清楚地表明其中一个不起作用(对于打印函数,它应该返回-1,这是无效的根据当前流的方向)。

不幸的是,检查标准库函数中的错误的常见模式是:

if (wprintf(...) == -1) { perror("wprintf"); ... }

这里可能没什么用处:如果将流设置为输出非宽字符,并且您拨打wprintf,则可能未设置errno并且您将获得{{1} },它没有提供太多信息。

所以当你不了解溪流的角色定位时,这确实是一个有点难以理解的问题。