【问题标题】:Stop getline() input when user types delimiter character当用户键入分隔符时停止 getline() 输入
【发布时间】:2020-06-05 01:56:49
【问题描述】:

当用户在我的练习应用程序的 getline 函数中输入分隔符时,我正在尝试找到一种无需按 Enter 即可停止输入的方法。

目前,只有当用户在输入分隔符后按下 Enter 并且 cout 消息向用户解释它时,来自 getline 的输入流才会被中断,但最好我希望输入在按下分隔符时简单地停止。

寻找有关在检测到指定字符时如何停止输入的建议。

这是我的完整代码:

#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';
}

输入/输出在这个周围(粗体是我的输入)

键入您要用来表示消息结束的字符

}

输入您的信息,随意填写。完成输入 输入 } 符号,然后在 } 符号后输入 Enter 丢了

asdf}asdf

asdf

【问题讨论】:

  • 您将无法使用标准流执行此操作。 cin 是“行缓冲”,因此您必须点击 enter 才能填充缓冲区。
  • @NathanOliver 这不是真的,通常是最终用户的终端被行缓冲。
  • curses 适合与终端交互
  • @AsteroidsWithWings 如何在标准 C++ 中关闭行缓冲,以便无需用户按 Enter 即可从 stdin/cin 读取字符?
  • @TedLyngmo 你不会,我也没说你可以。但那是 因为 cin 不是做线路缓冲的东西。 (如果是这样,将任意“二进制”数据传送到您的 C++ 应用程序将非常可怕......)

标签: c++ input getline


【解决方案1】:

使用standard-c/c++,您将无法访问控制台输入,直到用户使用回车发送它。唯一的方法是直接访问终端,但由于每个操作系统使用不同的控制台,因此需要特定于操作系统的解决方案。

windows 上,您可以使用 &lt;conio.h&gt;_getch() 或 WinApi ReadConsoleInput 执行此操作。

unix 上,您可以使用 &lt;termios.h&gt;&lt;curses.h&gt;

跨平台库,适用于所有操作系统:
NCurses

synchronet 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;
}

注意事项:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-25
    • 2021-07-27
    • 2021-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多