在下面的程序中,我正在尝试改进函数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
?
答案 0 :(得分:1)
你在这里尝试的方法是如此脆弱,以至于不可能。 GetCharAt()
假定输出的每个字符都是可打印的,并且没有任何东西在移动光标。您的SetCursorPosition()
就是这样做的,所以跟踪到目前为止输出的内容的想法根本不起作用。
另外,其他进程可能会在程序中间向控制台输出内容,例如来自root的wall
消息。您想要的是“ncurses”,http://en.wikipedia.org/wiki/Ncurses,这个库可能已经存在于您的系统中。它已经以独立于终端的方式解决了这些问题,并提供了一整套功能,可以在终端中移动屏幕,滚动,绘图,颜色等。