在控制台中“冻结”输入线并在其上方的线上打印?

时间:2016-07-06 17:12:11

标签: c input printf output scanf

我想知道是否有办法“冻结”输入行,以便在c中将输入和输出分开。例如,我的控制台输出目前是这样的:

1 OutputLine1
2 OutputLine2

但我希望它是这样的:

1 OutputLine1
2 OutputLine2
3 Enter a Command:

我希望它能够在程序收到数据流时进行更改。因此,当它运行时,它将是这样的

1 OutputLine1
2 OutputLine2
3 OutputLine3
4 Enter a Command:

要改为:

1 OutputLine1
2 OutputLine2
3 OutputLine3
4 OutputLine4
5 Enter a Command:

我目前正在使用printf()来获取所有输出,但似乎在这种情况下不会起作用。我可以使用其他任何打印/输入库吗?

提前致谢!!

2 个答案:

答案 0 :(得分:1)

这适用于大多数终端(特别是在xterm中),我认为它比设置curses更容易:

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

int main(){
    int lineno=1;
    int c;
    struct termios old_tio;
    struct termios new_tio;
    tcgetattr(STDIN_FILENO,&old_tio);
    new_tio=old_tio;
    new_tio.c_lflag &= (~ICANON&~ECHO);
    tcsetattr(STDIN_FILENO,TCSANOW,&new_tio);
    setvbuf(stdout,NULL,_IONBF,0);
    while(1){
        printf("%4d Enter a command: ",lineno);
        c=getchar();
        printf("\033[2K\033[50D%4d Command was %c\n",lineno++, c);
        if(c=='q'){
            break;
        }
    }
    tcsetattr(STDIN_FILENO,TCSANOW,&old_tio);
    return 0;
}

输出看起来OP想要的东西:

evaitl@evbb ~/se $ ./foo 
   1 Command was a
   2 Command was b
   3 Command was c
   4 Command was d
   5 Command was q
   6 Enter a command: 

参考:unbuffered IO

vt102 escapes

答案 1 :(得分:0)

假设您的终端允许VT100 escape codes,您可以尝试:

printf("OutputLine1\n");
printf("OutputLine2\n");
printf("OutputLine3\n");
printf("Enter a command: ");
// wait for input or more output

// if more output is ready, clear prompt
printf("\033[2K"); // VT100 clearline escape code (^[[2K)
printf("\r");      // Carriage return to return cursor to beginning of line
printf("OutputLine4\n");
// print prompt again
printf("Enter a command: ");
// wait for input or more output