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 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.
As explained by Jonathan Leffler in the comment, your code needs two modifications:
'\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.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With