-1

C++ に慣れるために、古い大学の OS 課題をやり直しています。それは、独自のシェルをプログラムすることです。私が最初に取り組んだことは、コマンドを受け入れることでしたが、私のアプローチでは、いくつかの機能が望まれていました。ここに私が持っているものがあります:

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、プロンプトを出力し、最後にユーザーの入力を待ちます。このプロンプトが長い場合、コマンドが 2 行にわたって実行されるまでに数文字しかかかりません。入力して折り返してEnterキーを押すと、すべて正常に機能します。2 行目に折り返して最初の行にバックスペースを戻したい場合、カーソルは新しい行の最初の文字で停止し、希望どおりに最初の行に「アンラップ」しません。このアンラップ動作を実現するには、ここで何ができますか?

問題は、'\b' を印刷しようとしてもラップが解除されないことだと思いますが、別の方法についてのアイデアがありません。これを特別なケースとそのコードとして扱う必要がないことを望んでいます。行の途中でバックスペースを使用すると、行の先頭でも機能します。

4

1 に答える 1

1

winapi を使用する必要があります。SetConsoleCursorPosition役に立ちます。以下は、カーソルを現在の位置から 1 行上に移動する最小限の例です。

#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 に答える