Jeremy的帖子非常详细。我会再添加一个可用的选项:跟踪正在输入的用户输入的字符,直到他最终按下ENTER。这样,当远程用户输入文本时,你所要做的就是:
向终端输出适当数量的退格字符('\b')(即与本地用户键入的文本长度相同),然后输出新的输入行文本,并输出本地用户之前键入的所有字符。然后继续正常进行。
它看起来就像新输入的文本“滑动”到了正确位置。
getch()
或getche()
函数:http://en.wikipedia.org/wiki/Conio.h - hyde#include <Conio.h>
#include <mutex> // C++11, if not C++11 find your own mutex
std::vector<char> inputBuffer;
std::mutex inputGuard;
struct Locker {
std::mutex* m;
Locker(std::mutex& m_):m(&m_) { m->lock(); }
void release() { if (m) m->unlock(); m = 0; }
~Locker() { release(); }
}
void AddToInputBuffer( char c ) {
Locker lock(inputGuard);
inputBuffer.push_back(c);
printf("%c",c);
}
std::string FinishInputBuffer() {
Locker lock(inputGuard);
std::string retval( inputBuffer.begin(), inputBuffer.end() );
inputBuffer.clear();
printf("\n");
return retval;
}
void OverlappedPrintln( std::string s ) {
Locker lock(inputGuard);
for (int i = 0; i < inputBuffer.size(); ++i) {
printf("%c", 8 /*backspace*/);
}
printf("%s\n", s.c_str());
for (int i = 0; i < inputBuffer.size(); ++i) {
printf("%c", inputBuffer[i]);
}
}
std::string readCharactersFromUser() {
// TODO: Handle exiting
while( int input = getch() ) {
if (input == '\n') {
return FinishInputBuffer();
AddToInputBuffer(input);
}
}
现在,将cin.getline(message, 256);
替换为std::string message = readCharactersFromuser()
,然后在执行(message[0] == 's' && message[1] == 'a' && message[2] == 'y' && message[3] == ' '
之前,检查字符串
的长度。
在程序的其他地方,用printf
代替,以构建一个std::string
并使用它调用OverlappedPrintln
。
这样做的效果是,当您想要打印输出时,锁定互斥量,在用户输入上回退,打印出消息,进行换行,然后打印您回退的文本,并释放您的互斥量。在99%的情况下,特别是在现代计算机速度下,不需要互斥量,但这是一种好的做法。
以上代码未经测试或编译。它的质量也不是最高的。
选择非回显获取字符是因为我无法在锁定状态下从用户输入读取,并且异步回显到输出可能会导致乱码。因此,我在互斥体内部进行读取而不回显,然后回显,以便inputBuffer
始终包含用户键入并已回显到屏幕上的字符。