在下面的程序中,我正在尝试在 linux C++控制台应用程序中改进函数GetCharAt
和SetCursorPosition
,该函数在给定位置返回字符,该函数将终端光标移至给定位置。但是每个功能都会相互干扰。例如在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,它可能已经存在于您的系统中。它已经以独立于终端的方式解决了这些问题,并提供了一系列功能,可在终端中在屏幕上四处移动,滚动,绘制,绘制颜色等。