Прекратить ввод getline (), когда пользователь вводит символ-разделитель - PullRequest
1 голос
/ 20 февраля 2020

Я пытаюсь найти способ остановить ввод без необходимости нажимать Enter, когда пользователь вводит символ-разделитель в функции getline в моем учебном приложении.

В настоящее время поток ввода из getline только прерывается если пользователь нажимает Enter после ввода символа-разделителя, и сообщение cout объясняет его пользователю, но предпочтительно, чтобы ввод был остановлен при нажатии разделителя.

Поиск предложений о том, как я могу остановить ввод, когда он обнаруживает указанный символ.

Вот полный код, который у меня есть:

#include <iostream>
#include <string>
#include <fstream>

using namespace std;

#define DEBUG 1 // 1 = enabled

int main()
{
    char takeFirstNonSpaceCharacter(string text);
    string message;
    char stopper;
    string stopperInput;

    cout << "Type the character with which you want to signal end of a message\n";
    cin >> stopperInput;
    cin.ignore(128, '\n'); //clean cin

    stopper = takeFirstNonSpaceCharacter(stopperInput); //in case input has white spaces
    cout << "Type your message, make it as long as you want.\n To finish typing enter the " << stopper << " symbol followed by Enter\n Input after the " << stopper << " symbol will be lost\n";

    getline(cin, message, stopper);
#if DEBUG == 1
    cout << message << '\n';
#endif
    system("pause");
    return 0;
}

char takeFirstNonSpaceCharacter(string text)
{
    string::const_iterator iter = text.begin();
    while (iter != text.end())
    {
        if (*iter != 32 || *iter != 10 || *iter != 9) //ascii: 32 = space, 10 = new line, 9 = horizontal tab
        {
            return *iter; //if its not space character then it must be a character (unless the user can somehow type for example \0 on keyboard)
        }
        else
        {
            iter++; //if its space
        }
    }
    return '\0';
}

С вводом / выводом быть рядом с этим (жирный шрифт - мой ввод)

Введите символ, которым вы хотите сообщить о завершении сообщения

}

Напечатайте свое сообщение, сделайте так, как вы хотите. Чтобы завершить ввод sh, введите символ}, а затем ввод ввода после того, как символ} будет потерян

asdf} asdf

asdf

1 Ответ

2 голосов
/ 20 февраля 2020

В стандарте -c / c ++ вы не сможете получить доступ к входу консоли, пока пользователь не отправит его с помощью ввода. Единственный способ - получить прямой доступ к терминалу, но поскольку каждая ОС использует разные консоли, для нее требуются решения, специфичные для ОС c.

Вкл. windows, вы можете сделать это с помощью <conio.h> _getch() или с WinApi ReadConsoleInput.

При unix вы можете использовать <termios.h> или <curses.h>

Кроссплатформенные библиотеки, которые работа на каждой ОС: NCurses

synchr onet ciolib

PDcurses

Вот пример кода для windows:

#include <conio.h>      // _getch()
#include <cctype>       // std::isspace
#include <string>       // std::getline
#include <iostream>     // std::cout
#include <algorithm>    // std::find_if_not

#define DEBUG

int main(void)
{
    int stopper;

    std::cout << "Type the character with which you want to signal end of a message" << std::endl;

    while (std::isspace(stopper = std::cin.get())) {} // oneliner instead of takeFirstNonSpaceCharacter
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // flush the rest of 

    // alternative oneliner without the need of pressing enter
    // do { stopper = _getch(); } while (std::isspace(stopper));

    std::cout << "Type your message, make it as long as you want." << std::endl;
    std::cout << "To finish typing, enter the " << (char)stopper << " symbol followed by Enter" << std::endl;
    std::cout << "Input after the " << (char)stopper << " symbol will be lost" << std::endl;

    std::string message;
    for(int ch = _getch(); ch != stopper; ch = _getch()) {
        _putch(ch); // print it, so the user can see his input
        message.push_back(ch); // concat it to the message buffer
    };

#ifdef DEBUG
    std::cout << std::endl << message << std::endl;
#endif
    getchar(); // system("pause"); is windows only, don't use that!
    return 0;
}

Примечания:

...