简体   繁体   中英

Windows version of wcswidth_l

I have some text to write to the Windows console that I need to know the real width of in columns. wcswidth_l seems to be the best option on platforms that have it (though mbswidth_l() would be better since I have no desire to use wchar_t, but for some reason it doesn't exist). But in addition to other platforms, I need something that works on Windows. Although it's unlikely that there's a portable solution, I don't know of any solution at all on Windows. I think the console has an API for getting cursor position and such, so I could write the text out and check the change in position. That would be accurate I guess, but writing out extra output isn't acceptable at all.

How does one go about getting the column width of a string or character on Windows?

Edit:

wcswidth_l returns the number of console columns used to display a string. Some characters take up one column and others, eg japanese characters, take up two.

As an example the 'column width' of "a あ" is four. 'a' is one, ' ' is one, and 'あ' is two. (Assuming the console is set up to actually display non-ascii characters that is). Also it'd be nice if the API supports strings using codepage 65001 (UTF-8).

Portable approach

Since width of characters depends more on characters themselves rather than the system on which they are displayed (ok, there might be excepetions, but they should be rather rare), one can use separate function to do that (on Windows too). This requires Unicode characters as it makes it much easier to analyze width of strings, but one for sure can write a wrapper to convert between encodings.

Available implementation

Here is suitable and portable implementation, which one can plug in into his application and fallback to use it on Windows.

First of all, the Windows Console API is located here .

Secondly, is the function you're looking for GetConsoleFontSize ?

I'll try to quickly type an example in a second.

EDIT: Here you go. Forgive me if it there's a small error. I actually found it was even easier. GetCurrentConsoleFont fills in a COORD structure on the way to you getting the index to pass to GetConsoleFontSize , so step saved :)

#define _WIN32_WINNT 0x0501 //XP, 0x0601=windows 7
#include <windows.h>

int main()
{
    HANDLE hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE);

    CONSOLE_FONT_INFO cfi;
    GetCurrentConsoleFont (hStdOutput, FALSE, &cfi);

    //cfi.dwFontSize.X == x size
    //cfi.dwFontSize.Y == y size
}

EDIT:

If you don't mind invisible output, you can use CreateConsoleScreenBuffer to pretty much have an invisible console window at your command while leaving yours unaffected. GetConsoleScreenBufferInfoEx will tell you the cursor position, at which point you can use WriteConsole to write to your buffer (invisibly), and check the cursor location again versus the number of characters actually written. Note that checking the cursor location beforehand would not require clearing the screen to use this method.

If you cannot afford to do extra output, visible or invisible, I'm not sure there really is a possibility.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM