C++ 如何在没有 ncurses 的情况下同时获取输入和输出(LINUX/MAC)

问题描述 投票:0回答:1

我试图让输入和输出同时工作,但输出不会弄乱它。我让它可以在 Windows 上使用,但不能在 linux/mac 上使用(用于从终端获取该行,以便我可以在所选输出文本下方打印它)

代码:

#include <iostream>
#include <string>
#include <thread>
#include <atomic>
#include <chrono>

#if defined(_WIN32)
#include <windows.h>
#include <conio.h>
#elif defined(__unix__) || defined(__APPLE__)
//libraries needed
#endif

using namespace std;

void ReadCin(atomic<bool>& run)
{
    string buffer;

    while (run.load())
    {
        getline(cin, buffer);

        if (buffer == "Quit")
        {
            run.store(false);
        }
    }
}

string get_terminal_line()
{
    string line;

#if defined(_WIN32)
    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    if (GetConsoleScreenBufferInfo(hStdOut, &csbi))
    {
        DWORD dwSize = csbi.dwSize.X;
        COORD cursorPos = csbi.dwCursorPosition;
        cursorPos.X = 0;
        SetConsoleCursorPosition(hStdOut, cursorPos);

        for (DWORD i = 0; i < dwSize; ++i)
        {
            char ch;
            DWORD charsRead;
            if (ReadConsoleOutputCharacterA(hStdOut, &ch, 1, cursorPos, &charsRead))
            {
                line += ch;
                cursorPos.X++;
            }
            else
            {
                break;
            }
        }

        SetConsoleCursorPosition(hStdOut, csbi.dwCursorPosition);
    }

#elif defined(__unix__) || defined(__APPLE__)
    //here
#endif

    size_t end = line.find_last_not_of(' ');
    if (end != string::npos)
    {
        line.erase(end + 1);
    }
    else
    {
        line.clear();
    }

    return line;
}

void PrintNewLine(atomic<bool>& run)
{
    while (run.load())
    {
        this_thread::sleep_for(chrono::seconds(2));

        string line = get_terminal_line();

        cout << "\33[2K\rNew line printed every 10 seconds" << endl;

        bool is_space = true;

        for (size_t length = 0; length != line.length(); length++)
        {
            if (isspace(line[length]) == false)
            {
                is_space = false;
                break;
            }
        }

        if (is_space == false)
        {
            cout << line;
        }
    }
}

int main()
{
    atomic<bool> run(true);
    thread cinThread(ReadCin, ref(run));
    thread printThread(PrintNewLine, ref(run));

    while (run.load())
    {
      //idk what to put here, so i'm just gonna leave it empty
    }

    run.store(false);
    cinThread.join();
    printThread.join();

    return 0;
}

我希望它可以在 Mac 和 Linux 上使用(因此上面的宏定义),它只是从终端获取该行。

c++ linux macos conio
1个回答
0
投票

在 Linux 中,您可以使用

tcsetattr
函数控制终端输入/输出,该函数允许您控制程序和终端之间的内核/驱动程序中发生的各种事情。

如果我明白你在问什么,你想要的是关闭键盘输入的自动回显,这样你就可以将其与输出正确定位。 您可以使用

ECHO
标志来执行此操作:

#include <termios.h>



     struct termios term;
     tcgetattr(0, &term);    // get the setting on the terminal connected to stdin
     term.c_lflag &= ~ECHO;  // turn off the ECHO flag
     tcsetattr(0, TCSANOW, &term);
© www.soinside.com 2019 - 2024. All rights reserved.