Outputting unicode characters in windows terminal

2020-02-01 08:31发布

问题:

Over the past week I've been working on a roguelike game in C++ along with a friend. Mostly too learn the language.

I'm using:

  • pdcurses
  • Windows 7
  • Visual studio C++

To output wchar_t's wherever I want to in the console. I have succeeded in otuputting some unicode characters such as \u263B (☻), but others such as \u2638 (☸) will just end up as question marks(?).

Here's the relevant code I use for output.

// Container of room information

struct RoomInfo
{
    wchar_t * layout;
    int width;
    int height;
};

// The following function builds RoomInfo 

RoomInfo Room::examine(IActor * examinor)
{
    RoomInfo ri;
    ri.width = this->width;
    ri.height = this->height;
    ri.layout = new wchar_t[height * width];
    for(unsigned int y = 0; y < height; y++)
    {
        for(unsigned int x = 0; x < width; x++)
        {
            ri.layout[y*width + x] = L'\u263B'; // works
            //ri.layout[y*width + x] = L'\u2638'; // will not work
        }
    }
}

// The following function outputs RoomInfo

void CursesConsole::printRoom(RoomInfo room)
{
    int w = room.width;
    int h = room.height;

    WINDOW * mapw = newwin(h, w, 1, 0);
    for(int y = 0; y < h; y++)
    {
        wmove(mapw, y, 0);
        for(int x = 0; x < w; x++)
        {
            int c = y*w + x;
            waddch(mapw, room.layout[c]);
        }
    }

    wrefresh(mapw);
    delwin(mapw);
}

I could of course fall back on boring ANSI-characters. But it would be really awesome to have the complete unicode-set of characters to play with.

To sum it up: How do you make sure that unicode characters are outputted correctly?


Edit:

Ok, so I figured out my encoding is working correctly. The problem is that I need to force the terminal to switch to a more unicode-rich font face. Is there a cross-platform way to do this? is there even a windows specific way to do this?

回答1:

The problem is that I need to force the terminal to switch to a more unicode-rich font face. Is there a cross-platform way to do this? is there even a windows specific way to do this?

I had a look for this, but couldn't find a Windows API call to do it (which may just mean I didn't find it, of course). I would not expect to find a cross-platform way to do it.

The best solution I can think of is to launch the console using a specially constructed Shell Link (.LNK) file. If you read the file format documentation, you'll see that it allows you to specify a font.

But your problems don't end there. A Western locale install of Windows provides Lucida Console, but that font only provides a limited subset of graphemes. I assume that you can output/input Japanese text in the console on a Japanese Windows PC. You'd need to check what is available on a Japanese Windows if you wanted to be sure it would work there.

Linux (Ubuntu, at least) seems to have much better support here, using UTF-8 and providing a font with broad grapheme support. I haven't checked other distros to see what the story is there, nor have I checked how fonts are resolved in the terminal (whether it's an X thing, a Gnome thing or whatever).



回答2:

In principle, all unicode characters are supported on the console. The fact that you're seeing question marks probably has to do with font support for those characters. Try switching the console font to something with very good unicode support.



回答3:

You need to set the code page properly. There's a pretty good article about that here: link



回答4:

Although it's a pretty big switch, you might try using an alternative console, especially if you are doing a roguelike. libtcod is a moderately popular library, written in C with C++ bindings, that provides a full color console which you can set up your own fonts and glyphs in. That should give you a lot more flexibility than being stuck with what the Windows console gives you.