使用system(“ / bin / stty raw”)时的奇怪输出行为

时间:2019-01-02 07:51:54

标签: c

在我的程序中,显示5x20的点域。具有符号“#”的玩家也在场上。您可以使用w,a,s和d移动播放器。如果我使用缓冲输入,一切都很好。但是用户不想每次都按回车。所以我使用了命令

system("/bin/stty raw")

现在的问题是输出行为非常奇怪。该字段的行现在无法正确显示。我浪费了很多时间试图自己找出错误。而且Google似乎对此行为没有适当的解释。

你能告诉我为什么程序表现得这么奇怪,以及如何解决吗?

#include <stdio.h>

#define FIELD_VERTIKAL 5
#define FIELD_HORIZONTAL 20
#define PLAYER_SYMBOL '#'

void print_field(char field[FIELD_VERTIKAL][FIELD_HORIZONTAL])
{
    // reset display
    for (int i = 0; i < 20; i++)
        putchar('\n');

    // display field
    for (int i = 0; i < FIELD_VERTIKAL; i++)
    {
        for (int j = 0; j < FIELD_HORIZONTAL; j++)
            putchar(field[i][j]);
        putchar('\n');  
    }
}

void draw_field(char field[FIELD_VERTIKAL][FIELD_HORIZONTAL], 
  int pos_vertikal, int pos_horizontal)
{
    for (int i = 0; i < FIELD_VERTIKAL; i++)
        for (int j = 0; j < FIELD_HORIZONTAL; j++)
            field[i][j] = '.';
    field[pos_vertikal][pos_horizontal] = '#';
}

int main() 
{
    // create field and initialize it
    char field[FIELD_VERTIKAL][FIELD_HORIZONTAL];   

    // position of player
    int pos_vertikal = 0;
    int pos_horizontal = 0;

    // initialize field
    draw_field(field, pos_vertikal, pos_horizontal);

    system("/bin/stty raw");
    print_field(field);
    char input;
    while ((input = getchar()) != EOF) 
    {
        // move player
        if (input == 'w')
        {
            pos_vertikal--;
        }
        else if (input == 'a')
        {
            pos_horizontal--;
        }
        else if (input == 's')
        {
            pos_vertikal++;
        }
        else if (input == 'd')
        {
            pos_horizontal++;
        }

        // place player and display field
        draw_field(field, pos_vertikal, pos_horizontal);
        print_field(field);
    }
}

1 个答案:

答案 0 :(得分:4)

Terminals是非常复杂的设备(今天的terminal emulators试图模仿它们,类似于VT100;当然,这些仿真器是operating-system特有的)。阅读TTY demystified页和termios(3)。另请注意ANSI escape codes

stty raw并没有实现您的梦想(与line discipline有关)。另请参见stty(1)pty(7)

如果要编写面向终端文本的应用程序,请使用诸如ncurses之类的库。因此,扔掉代码,花几天时间阅读文档,然后从头开始编写代码。

也许您可以考虑将游戏制作成一些图形应用程序,例如通过使用诸如GTKlibSDL之类的工具包。

PS。您没有提到它,但是我想您正在使用某些Linux系统。