Home > Enterprise >  In linux program cannot erase utf-8 character completely using backspace
In linux program cannot erase utf-8 character completely using backspace

Time:01-02

I have a C program which waits for user's input

#include <stdio.h>

int main()
{   
    getchar();

    return 0;
}

Now I run it and input some Chinese characters like 测试测试. Then now I click backspace, I found I cannot erase these characters completely(some blank remained)

I found termios has a flag setting IUTF8, but why it doesn't work?


UPDATE ON 2022/12/31:

I am trying to describe my question more detailed, I have a program like this

png1

Now I run it and enter some Chinese characters(without Enter key)

png2

Then I keep clicking Backspace key(until nothing can be erased any more), but half of the content still display on my screen. It's so abnormal, how can I make the erase perform well?

png3

I know it is a stupid question for you. I just want to make it more comfortable when typing some UTF8 characters(like Chinese characters).

I found the shell can handle this well, how can I do to make my program perform the same?

By the way, this is my locale output

LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC=zh_CN.UTF-8
LC_TIME=zh_CN.UTF-8
LC_COLLATE="en_US.UTF-8"
LC_MONETARY=zh_CN.UTF-8
LC_MESSAGES="en_US.UTF-8"
LC_PAPER=zh_CN.UTF-8
LC_NAME=zh_CN.UTF-8
LC_ADDRESS=zh_CN.UTF-8
LC_TELEPHONE=zh_CN.UTF-8
LC_MEASUREMENT=zh_CN.UTF-8
LC_IDENTIFICATION=zh_CN.UTF-8
LC_ALL=

CodePudding user response:

Use GNU readline to provide a shell-like interface, with Tab autocompletion, correct input handling, et cetera.

To compile the following example program, make sure you have the libreadline-dev package installed. The readline library needed to run the program will already be installed, because so many applications that are installed by default require it already.

// SPDX-License-Identifier: CC0-1.0
// Compile using
//    gcc -Wall -O2 $(pkg-config --cflags readline) example.c $(pkg-config --libs readline) -o example

#define  _GNU_SOURCE
#include <stdlib.h>
#include <locale.h>
#include <readline/readline.h>
#include <readline/history.h>
#include <stdio.h>

int main(void)
{
    char *line;

    setlocale(LC_ALL, "");

    while (1) {
        line = readline(NULL);  // No prompt

        // Input line is in 'line'; exit if end of input or empty line.
        if (!line || *line == '\0')
            break;

        // Do something with 'line'

        // Discard the dynamically allocated line
        free(line);
    }

    return 0;
}

When using the GNU readline library, the library takes over the standard input, and handles character deletion (and many other things) at the terminal (termios) level. It works absolutely fine with file and pipe inputs as well, and is what e.g. bash shell uses for interactive input.

  • Related