简体   繁体   中英

Cannot correctly print extended ASCII characters in NCURSES

I have this program:

#include <ncurses.h>
int main () {
    initscr();
    mvaddstr(0, 0, "              A         B         C         D         E       ");
    mvaddstr(1, 24, "ñandñ");
    mvaddstr(1, 34, "esdrñjulñ");
    refresh();
    getch();
    endwin();
    return 0;
}

When ncurses prints the first word (ñandñ) something happens that when moving to another position afterwards (in this case to 1, 34), actually it moves to another position, so the second word gets printed in another column.

So what it should look like:

          A         B         C         D         E       
                              ñandñ     esdrñjulñ

looks like this:

          A         B         C         D         E       
                              ñandñ   esdrñjulñ

because of the two 'ñ' extended ascii char in the first word.

Any idea what is wrong? Thanks!

If you want to use multibyte UTF-8 characters, you must use the version of the ncurses library compiled with multibyte support, and you need to set the locale correctly at the beginning of your program.

The multibyte ncurses library is usually called libncursesw , so to use it is is sufficient to change -lncurses to -lncursesw in your linker options. You do not need a different header file. However, if you actually want to use the wide-character functions, you must #define the symbol _XOPEN_SOURCE_EXTENDED before any #include directive. The easiest way to do that with gcc (or clang) is to add -D_XOPEN_SOURCE_EXTENDED to your compiler options.

If your shell's locale has been set to a UTF-8 locale (which will usually be the case on a modern Linux distribution), it is sufficient to insert

setlocale(LC_ALL, "");

before any call to an ncurses routine. That sets the executable's locale to the locale configured by the environment variables. You'll need to add

#include <locale.h>

to your header includes. No special library needs to be linked for locale support.


The original question indicated that mvaddwstr was being used. That's generally a better solution for multibyte characters, but as indicated above, you can use the narrow string interfaces if you want to. However, you cannot output incomplete UTF-8 sequences, so the single-character narrow interfaces like addch can only be used with character codes less than 128.

This note applied to an attempt to call mvaddwstr with a char* instead of a wchar_t* argument. Don't do that:

Like all of the w ncurses functions which accept strings, mvaddwstr takes a wchar_t* as its string argument. Your compiler should have warned you about that (unless it warned you that there was no prototype for mvaddwstr ). So the strings should be prefixed with the L length attribute: L"ñandñ" .

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