如何从C语言中删除Linux终端中的字符

时间:2017-06-11 20:42:58

标签: 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*sizeof(char));
    *(buf+0)=KEY_BACKSPACE;
    *(buf+1)=' ';
    *(buf+2)=KEY_BACKSPACE;
    write(1,buf,3);
    free(buf);
}

这只是展示这种技术的一个小例子。在原始程序中,我禁用了规范模式并自己处理每次击键。这就是我需要删除字符的原因。

写入退格键,空格,退格键在我的原始程序中运行良好。现在,当我在几年后运行相同的程序时,它没有删除任何东西。改变了什么?我该怎么做才能解决这个问题?

2 个答案:

答案 0 :(得分:2)

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

  • 典型终端(模拟器)理解的rubout字符为'\b'(或8),而不是127。
  • 写入TTY时,默认情况下
  • printf()是行缓冲的。这意味着您需要在致电fflush(stdout)printf()之间致电write()。如果没有刷新abc只会在程序出口处打印,那么删除序列将在之前发出它应该删除的内容,这会使其失效。

答案 1 :(得分:2)

正如我在comment中所述,您需要使用退格而不是'\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秒):

abc
然后(再过2秒):

ab

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