简体   繁体   中英

How to remove a character from a Linux terminal in C

How can I remove a character on the terminal before the cursor in Linux? In the past I used something like this:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define KEY_BACKSPACE 127

int main(){
    printf("%s", "abc"); // add something so we can see if delete works
    char * buf = malloc(3*sizeof(char));
    *(buf+0)=KEY_BACKSPACE;
    *(buf+1)=' ';
    *(buf+2)=KEY_BACKSPACE;
    write(1,buf,3);
    free(buf);
}

This is only a small example demonstrating this technique. In the original program I disabled canonical mode and handled every keystroke myself. That's why I needed to remove characters.

Writing backspace, space, backspace worked fine in my original program. Now when I run same program after a few years, it didn't remove anything. What changed? What can I do to fix this?

As explained by Jonathan Leffler in the comment, your code needs two modifications:

  • The rubout character understood by the typical terminal (emulator) is '\\b' (or 8), not 127.
  • printf() is line-buffered by default when writing to a TTY. This means that you need to call fflush(stdout) between calls to printf() and write() . Without flushing abc will only be printed at program exit, so the deletion sequence will be emitted before the contents it is supposed to delete, which renders it inoperative.

As I noted in a comment , you need to use backspace instead of '\\177' (or '\\x7F' ) to move backwards. You also have to worry about buffering of standard I/O. It's often best not to use a mixture of standard I/O and file descriptor I/O on the same stream — standard output in this example. Use one or the other, but not both.

This works:

#include <unistd.h>

int main(void)
{
    char buff1[] = "abc";
    char buff2[] = "\b \b";
    write(STDOUT_FILENO, buff1, sizeof(buff1) - 1);
    sleep(2);
    write(STDOUT_FILENO, buff2, sizeof(buff2) - 1);
    sleep(2);
    write(STDOUT_FILENO, "\n", 1);
    return 0;
}

It shows first (for 2 seconds):

abc

then (for another 2 seconds):

ab

then it exits. The cursor is after c at first, then after b .

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