如何在C中打印Box字符(Windows)

时间:2017-08-06 15:18:47

标签: c windows unicode special-characters

如何在C中打印em破折号?

其中一个: -

每当我这样做:printf("—")我只是在终端获得ù

谢谢。

编辑:下面的代码应该打印出一个Xs和一个Os看起来网格,其中包含em破折号的水平线。

int main ()
{
    char grid[3][3] = {{'a', 'a', 'a'}, {'a', 'a', 'a'}, {'a', 'a', 'a'}};

    int i, j;

    for (i = 0; i < 3; i++) {
        for (j = 0; j < 3; j++) {
            if (j != 0)
            {
                printf("|");
            }
            printf("  %c  ", grid[i][j]);
        }
        if (i != 2)
        {
            printf("\n——————————————\n");
        }
    }

    return 0;
}

输出:(“ù”应为“ - ”s)

  a  |  a  |  a
ùùùùùùùùùùùù
  a  |  a  |  a
ùùùùùùùùùùùù
  a  |  a  |  a

编辑:我在Windows 10 x64上使用Codeblocks 16.01 with C11。

编辑:我被告知盒子字符,问题已变成如何打印,因此标题和标签更改。

1 个答案:

答案 0 :(得分:5)

在标准C中,您使用宽字符和宽字符串:

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

int main(void)
{
    setlocale(LC_ALL, "");
    fwide(stdout, 1);

    wprintf(L" \n");

    wprintf(L"   │   │   \n");
    wprintf(L"───┼───┼───\n");
    wprintf(L"   │   │   \n");
    wprintf(L"───┼───┼───\n");
    wprintf(L"   │   │   \n");

    return EXIT_SUCCESS;
}

您可以使用广泛的字符常量,例如L'┼'; printf()wprintf()函数的转换说明符为%lc。类似地,宽字符串常量具有L前缀,其转换说明符为%ls

不幸的是,您仅限于Microsoft提供的C版本,因此它可能适用于您,也可能不适用。

上述代码在Windows中不起作用,因为Microsoft不希望它。有关详细信息,请参阅setlocale()上的Microsoft文档:

  

可用区域设置名称,语言,国家/地区代码和代码页的集合包括Windows NLS API支持的所有内容,除了每个字符需要两个以上字节的代码页,例如UTF-7和UTF-8

换句话说,Microsoft的C本地化仅限于单字节代码页,并且特别排除任何Unicode语言环境。然而,这纯粹是微软EEE战略的一部分,它将你,一个崭露头角的开发人员绑定到微软自己的围墙花园,这样你就不会编写实际的可移植C代码(或恐怖的恐怖,利用POSIX C),但精神上锁定到Microsoft模型。你看,你可以使用_setmode()来启用Unicode输出。

由于我自己根本不使用Windows,因此无法验证以下特定于Windows的解决方法是否有效,但值得尝试。 (请在评论中报告您的发现,Windows用户,所以我可以修复/包括这部分答案。)

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

#ifdef _WIN32
#include <io.h>
#include <fcntl.h>

static int set_wide_stream(FILE *stream)
{
    return _setmode(_fileno(stream), _O_U16TEXT);
}

#else

static int set_wide_stream(FILE *stream)
{
    return fwide(stream, 1);
}

#endif

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

    /* After this call, you must use wprintf(),
       fwprintf(), fputws(), putwc(), fputwc()
       -- i.e. only wide print/scan functions
       with this stream.
       You can print a narrow string using e.g.
       wprintf(L"%s\n", "Hello, world!");
    */
    set_wide_stream(stdout, 1);

    /* These may not work in Windows, because
       the code points are 0x1F785 .. 0x1F7AE
       and Windows is probably limited to
       Unicode 0x0000 .. 0xFFFF */
    wprintf(L" \n");

    /* These are from the Box Drawing Unicode block,
       U+2500 ─, U+2502 │, and U+253C ┼,
       and should work everywhere. */
    wprintf(L"   │   │   \n");
    wprintf(L"───┼───┼───\n");
    wprintf(L"   │   │   \n");
    wprintf(L"───┼───┼───\n");
    wprintf(L"   │   │   \n");

    return EXIT_SUCCESS;
}