在linux控制台应用程序中的给定位置获取一个字符

时间:2013-09-05 20:01:11

标签: c++ linux terminal console-application

在下面的程序中,我正在尝试改进函数GetCharAt,它返回给定位置的字符,SetCursorPosition将终端光标移动到给定位置,在 linux中 C ++控制台应用程序。但每个功能都会干扰另一个功能。例如,在main中,注释掉SetCursorPosition会恢复GetCharAt的正常功能。

#include <streambuf>
#include <iostream>
using namespace std;
#include <stdio.h>

string console_string;

struct capturebuf : public streambuf
{
    streambuf* d_sbuf;

public:
    capturebuf():
        d_sbuf(cout.rdbuf())

    {
        cout.rdbuf(this);
    }
    ~capturebuf()
    {
        cout.rdbuf(this -> d_sbuf);
    }
    int overflow(int c)
    {
        if (c != char_traits<char>::eof())
        {
            console_string.push_back(c);
        }
        return this -> d_sbuf->sputc(c);
    }
    int sync()
    {
        return this -> d_sbuf->pubsync();
    }
} console_string_activator;

char GetCharAt(short x, short y)
{
    if(x < 1)
        x = 1;
    if(y < 1)
        y = 1;

    bool falg = false;
    unsigned i;
    for(i = 0; 1 < y; i++)
    {
        if(i >=  console_string.size())
            return 0;
        if(console_string[i] == '\n')
            y--;
    }
    unsigned j;
    for(j = 0; console_string[i + j] != '\n' && j < x; j++)
    {
        if(i + j >= console_string.size())
            return 0;
    }
    if(i + j - 1 < console_string.size())
        return console_string[i + j - 1];
    return 0;
}

void SetCursorPosition(short x,short y)
{
    char buffer1[33] = {0};
    char buffer2[33] = {0};

    string a = "\e[";

    sprintf(buffer1,"%i",y);
    sprintf(buffer2,"%i",x);

    string xx = buffer1;
    string yy = buffer2;

    cout<< a + xx + ";" + yy + "f";
    cout.flush();
}

void SetCursorPosition2(short x, short y)
{
    printf("\e[%i;%if",x,y);
    cout.flush();
}

int main()
{
    SetCursorPosition(1,1); // comment out this line for normal functionality
    cout << "hello" "\n";

    for(unsigned j = 1; j <= 5; j++)
    {
        printf("%c",GetCharAt(j,1));
    }
    cout<< "\n";
}

如何更改SetCursorPosition以便它不会干扰GetCharAt

1 个答案:

答案 0 :(得分:1)

你在这里尝试的方法是如此脆弱,以至于不可能。 GetCharAt()假定输出的每个字符都是可打印的,并且没有任何东西在移动光标。您的SetCursorPosition()就是这样做的,所以跟踪到目前为止输出的内容的想法根本不起作用。

另外,其他进程可能会在程序中间向控制台输出内容,例如来自root的wall消息。您想要的是“ncurses”,http://en.wikipedia.org/wiki/Ncurses,这个库可能已经存在于您的系统中。它已经以独立于终端的方式解决了这些问题,并提供了一整套功能,可以在终端中移动屏幕,滚动,绘图,颜色等。