在下面的程序中,我正在尝试在 linux C++控制台应用程序中改进函数GetCharAtSetCursorPosition,该函数在给定位置返回字符,该函数将终端光标移至给定位置。但是每个功能都会相互干扰。例如在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

最佳答案

您在此处尝试的方法非常脆弱,无法实现。 GetCharAt()假定输出的每个字符都是可打印的,并且没有游标在移动。您的SetCursorPosition()正是这样做的,因此跟踪到目前为止已输出的内容的想法根本行不通。

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

08-17 04:21