-1

为了更好地熟悉 C++,我正在重做一个旧的大学操作系统任务:编写自己的 shell。我处理的第一件事是接受命令,但我的方法留下了一些不足之处。这是我所拥有的:

string GetLine() {
    string line;
    char input = _getch();
    while (input != 13) {
        switch (input) {
        case 8: // backspace
            if (line.length() != 0) {
                line = line.substr(0, line.length() - 1);
                cout << "\b \b";
            }
            break;
        case -32: // all arrows' first byte
            input = _getch(); // distinctly different arrow byte
            switch (input) {
                case 72: // up
                    break;
                case 80: // down
                    break;
                case 75: // left
                    break;
                case 77: // right
                    break;
            }
            break;
        case 9: // tab
            break;
        default:
            line += input;
            cout << input;
            break;
        }
        input = _getch();
    }
    cout << endl;
    return line;
}

它工作得很好,我知道我与箭头键有更多关系(如果我什至可以正确区分它们的话)。我要问的主要问题是光标已经换到终端上的下一行的某种情况。为了模拟cmd.exe,我打印了一个提示并在其末尾等待用户输入。当这个提示很长时,我的命令只需要几个字符就可以跨两行运行。如果我只是输入它并让它环绕并按 Enter 一切正常。如果我换行到第二行并想退格回到第一行,光标会停在新行的第一个字符处,并且不会像我希望的那样“解开”回到第一行。我可以在这里做什么来实现这种展开行为?

我认为问题在于尝试打印 '\b' 不会解开,但我没有替代方案的想法,我希望我不必将其视为特殊情况和代码将在一行中间退格也将在一行的开头工作。

4

1 回答 1

1

你需要使用winapi,SetConsoleCursorPosition会帮助你。这是一个将光标从当前位置向上移动一行的最小示例:

#include <iostream>
#include <windows.h> 

int main() {
    std::cout << "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
        "aaaaaaaaaaaaaaa";
    HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);

    CONSOLE_SCREEN_BUFFER_INFO csbiInfo; 
    GetConsoleScreenBufferInfo(hStdout, &csbiInfo);
    csbiInfo.dwCursorPosition.Y -= 1; // Move Y coordinate up by one
    SetConsoleCursorPosition(hStdout, csbiInfo.dwCursorPosition);

    std::cin.get();
}

此外,控制台功能具有控制控制台的所有必要功能的完整列表。你会想在你的程序中使用这些。

您需要使用CreateConsoleScreenBuffer 创建自己的屏幕缓冲区,然后先将其设置为缓冲区。然后自己处理从控制台写入和读取的所有内容。

于 2013-03-29T22:16:14.763 回答