覆盖以前打印的内容时,如何在标准输出中打印几行?

时间:2019-04-18 08:09:03

标签: c printf carriage-return

我是一名学生,目前正在为大学项目开发​​Othello版本。

大部分已完成,因此我正在寻找可以改进的地方。其中之一是使板(已打印到stdout)仅在每次播放时替换前一个板,以确保终端不移动。

以下是最近这样做的尝试:

char c = ' ';
fflush(stdout);
contaPecas(e, pecas);
printf("\n\r* X-%d |SCORE| O-%d *   \n\r\n\r  1 2 3 4 5 6 7 8  "" | N <peça>para novo jogo "
       "em que o primeiro a jogar é o jogador com peça.\n\r", pecas->x, pecas->y);

for (int i = 0; i < 8; i++) {
    for (int j = 0; j < 8; j++) {
        if (j == 0)
            printf("%d ", i+1);

        if (opcao == 1 && verificaValida(i,j,turno) == 1)
            c = '.';
        else if (opcao == 2 && (*turno)->N != 0 && i == sugestao->y && j == sugestao->x)
            c = '?';
        else
            switch (e.grelha[i][j]) {
                case VALOR_O:
                    c = 'O';
                    break;
                case VALOR_X:
                    c = 'X';
                    break;
                case VAZIA:
                    c = '-';
                    break;
            }
        printf("%c ", c);
    }

    switch (i) {
            case 0:
                printf("  | A para novo jogo contra bot. O jogador comeca com peça X.\n\r");
                break;
            case 1:
                printf("  | L<ficheiro>para ler um jogo de ficheiro.\n\r");
                break;
            case 2:
                printf("  | E <ficheiro> escrever em ficheiro estado do jogo.\n\r");
                break;
            case 3:
                printf("  | J<L,C>jogar peça atual na posição (l,c).\n\r");
                break;
            case 4:
                printf("  | S para imprimir um ponto ‘.’nas posições com jogada válida.\n\r");
                break;
            case 5:
                printf("  | H para sugestão de jogada. Deve ser colocado um ‘?’no sitio sugerido.\n\r");
                break;
            case 6:
                printf("  | U para desfazer a última jogada(Undo).\n\r");
                break;
            case 7:
                printf("  | Q para sair do jogo.\n\r");
                break;
        }
    }
if (e.peca == 0) printf("\n\r");
else if (e.peca == VALOR_X) printf("Turn: X\n\r\n\r");
else printf("Turn: O\n\r\n\r");

if (opcao == 2 && (*turno)->N != 0)
    printf("A melhor jogada é %d %d.\n\r", sugestao->y+1, sugestao->x+1);

}

我期望使用fflush(stdout)可以擦除以前的打印内容,并且使用'\ r'可以将其写在与以前相同的位置,但是它会继续在已经写过的内容下进行写操作并制作终端移动。关于如何解决此问题的任何想法?

1 个答案:

答案 0 :(得分:2)

即使使用\r,标准功能(scanffgets ...)也会从stdin读取,直到按下 Return ,在这种情况下,光标总是向下(占用\n)到控制台的下一行。

您需要使用一些专门的库,可以在Unix上检查ncurses或Windows中的控制台API。

另一个选项(如果您使用的是vt100兼容终端)是使用控制台代码:

#define gotoxy(x,y) printf("\033[%d;%dH", (x), (y))

({man console_codes以获取更多信息)