【问题标题】:Output unicode wchar_t character输出 unicode wchar_t 字符
【发布时间】:2014-07-29 22:34:15
【问题描述】:

只是尝试使用 MinGW 在 C 中输出此 unicode 字符。我首先使用swprintf 将其放在缓冲区中,然后使用wprintf 将其写入标准输出。

#include <stdio.h>

int main(int argc, char **argv)
{
    wchar_t buffer[50];
    wchar_t c = L'☒';

    swprintf(buffer, L"The character is: %c.", c);
    wprintf(buffer);

    return 0;
}

Windows 8 下的输出为:

字符是:.

Ɣ 等其他字符也不起作用。

我做错了什么?

【问题讨论】:

  • swprintf 有一个大小作为第二个参数。您还必须包含 wchar.h 标准标题。
  • 你是对的,但我认为我使用的是 Windows 版本的swprintf,它不需要大小作为第二个参数。
  • 我没有收到编译器错误,这表明我正在使用 Microsoft 的 swprintf。我认为windows.h 也会自动包含在内。
  • @cdonts:不,不是。它可能由您的编译器假定,但不会自动包含在内。你没有收到关于使用没有正确原型(或类似)的函数的警告吗?
  • MinGW 的 stdio.h 有以下评论:/* These differ from the ISO C prototypes, which have a maxlen parameter (like snprintf). */。似乎他们省略了它,因为他们尽可能多地使用msvcrt.dll 函数。我很困惑。啧啧啧啧。

标签: c unicode mingw


【解决方案1】:

要将 Unicode(或更准确地说是 UTF-16LE)输出到 Windows 控制台,您必须将文件转换模式更改为 _O_U16TEXT_O_WTEXT。后一个包括BOM,在这种情况下不感兴趣。

文件翻译模式可以用_setmode改变。但它需要一个文件描述符(缩写为fd)而不是FILE *!您可以从FILE *_fileno 获取相应的fd

这是一个应该适用于 MinGW 及其变体以及各种 Visual Studio 版本的示例。

#define _CRT_NON_CONFORMING_SWPRINTFS

#include <stdio.h>
#include <io.h>
#include <fcntl.h>

int
main(void)
{
    wchar_t buffer[50];
    wchar_t c = L'Ɣ';

    _setmode(_fileno(stdout), _O_U16TEXT);
    swprintf(buffer, L"The character is: %c.", c); 
    wprintf(buffer);

    return 0;
}

【讨论】:

【解决方案2】:

您正在使用%c,但%c 是用于char,即使您从wprintf() 使用它也是如此。使用%lc,因为参数是whar_t

swprintf(buffer, L"The character is: %lc.", c);

这种错误通常应该被编译器警告捕获,但并不总是发生。特别是,捕捉这个错误很棘手,因为 %c%lc 实际上 都采用 int 参数,而不是 charwchar_t(不同之处在于它们如何解释 int )。

【讨论】:

  • 感谢您的回答。你是对的,它应该是%lc,但仍然无法正常工作。
  • @cdonts:你的swprintf() 有问题,因为它没有大小参数。如果您按照您所说的那样使用 MinGW,那么事情就会变得很可疑。
  • 但是文档说没有size参数(至少this docs)。
  • @cdonts:这些医生 16 岁,足以在美国开车。
  • @cdonts:这是当前文档:msdn.microsoft.com/en-us/library/ybk95axf.aspx
【解决方案3】:

这对我有用:

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

int main(int argc, char **argv)
{
    wchar_t buffer[50];
    wchar_t c = L'☒';

    if (!setlocale(LC_CTYPE, "")) {
        fprintf(stderr, "Cannot set locale\n");
        return 1;
    }

    swprintf(buffer, sizeof buffer, L"The character is %lc.", c);
    wprintf(buffer);

    return 0;
}

我改变了什么:

  • 我添加了wchar.h包含使用swprintf所需要的
  • 我按照 C 的要求添加了 size 作为 swprintf 的第二个参数
  • 我将%c转换规范改为%lc
  • 我使用 setlocale 更改语言环境

【讨论】:

  • 感谢您的回答,但这给了我一个分段错误:|
  • @cdonts 可能是因为在 Windows 上 swprintf 出于某种原因不希望将大小作为第二个参数
  • @oauh 你是对的。现在没有分段错误,但仍然无法正常工作(我看不到字符)。
  • @cdonts 通过添加setlocale 调用它在Linux 上运行良好,我无法在MinGW 上对其进行测试,但我想setlocale 调用可能需要更改。
  • 这个答案被否决(感谢downvoter!)有点苛刻,因为上面的程序运行良好并且问题听起来与MinGW有关。
【解决方案4】:

此常见问题解答解释了如何在 MinGW 中使用 UniCode / 宽字符:

https://sourceforge.net/p/mingw-w64/wiki2/Unicode%20apps/

【讨论】:

    猜你喜欢
    • 2014-11-12
    • 2013-08-31
    • 1970-01-01
    • 1970-01-01
    • 2011-03-10
    • 2017-03-14
    • 2011-08-05
    • 2012-09-27
    • 2019-03-11
    相关资源
    最近更新 更多