如何在C中从Linux终端删除字符

如何在C中从Linux终端删除字符,c,linux,terminal,C,Linux,Terminal,在Linux中,如何删除终端上光标前的字符?过去我用过这样的东西: #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*s

在Linux中,如何删除终端上光标前的字符?过去我用过这样的东西:

#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);
}
#包括
#包括
#包括
#定义键\u退格127
int main(){
printf(“%s”,“abc”);//添加一些内容,以便我们可以查看删除是否有效
char*buf=malloc(3*sizeof(char));
*(buf+0)=键_退格;
*(buf+1)='';
*(buf+2)=键_退格;
写(1,buf,3);
免费(buf);
}
这只是演示此技术的一个小示例。在最初的程序中,我禁用了canonical模式,自己处理每一次击键。这就是为什么我需要删除字符


在我原来的程序中,写backspace,space,backspace效果很好。几年后,当我运行同一个程序时,它并没有删除任何内容。什么改变了?我能做些什么来解决这个问题?

正如Jonathan Leffler在评论中解释的那样,您的代码需要两个修改:

  • 典型终端(仿真器)理解的rubout字符是
    '\b'
    (或8),而不是127
  • 写入TTY时,
    printf()
    默认为行缓冲。这意味着您需要在调用
    printf()
    write()
    之间调用
    fflush(stdout)
    。如果不刷新,abc将仅在程序退出时打印,因此删除序列将在应该删除的内容之前发出,从而使其无法工作
正如我在a中指出的,您需要使用backspace而不是
'\177'
(或
'\x7F'
)来向后移动。您还必须担心标准I/O的缓冲。在本例中,最好不要在同一个流-标准输出上混合使用标准I/O和文件描述符I/O。使用其中一个,但不能同时使用两个

这项工作:

#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;
}
然后(再持续2秒钟):


然后它退出。光标首先在
c
之后,然后在
b

之后,使用“delete”键代码进行退格是很奇怪的;在大多数系统中,您需要使用退格
'\b'
。您还需要
fflush(stdout)
write()
覆盖部分字符串之前,将
abc
字符串显示在屏幕上。或者也可以使用
write()
打印
abc
字符串。我释放了缓冲区,如果是printf,则使用write。这不是我试图证明的问题。正如评论所指出的,问题在于使用127字符。(我不知道为什么会这样。)顺便说一句,谢谢你的快速评论。一个可能的解释是,你使用的终端仿真器(或终端)不遗余力地解释了即将到来的原始数据,而今天的终端仿真器不再这样做。
abc
ab