暂停功能永远循环

时间:2019-09-23 16:18:44

标签: c++ pause

我正在尝试在C ++中实现暂停功能,但是它会永远循环。

我正在使用macOS,但是我试图创建一个在任何系统上都可以使用的暂停功能...我相信我的cin >>不能从键盘上捕获'\ n'或'\ r'并且正在循环永远。

void Transferencia::pause() {
    char enter = 0;
    while(enter != '\n' && enter != '\r') {
        cout << "(Press Enter to Continue...) ";
        cin >> enter;
    }
    cin.clear();
}

我想暂停程序,直到用户按下“ enter”键。 但是即使我按下“输入/返回”键,它仍会循环播放...

3 个答案:

答案 0 :(得分:6)

起初:enter != '\n' || enter != '\r'是重言式:即使enter 等于其中一个字符,但 也不能等于另一个字符一。因此,其中一项测试必须是正确的……当enter不等于两个值时,您实际上想停留在循环中。

std::cin >> ...在您按Enter键之前不会读取数据,但是它将丢弃换行符(实际上是所有空格)。因此,仅需正确读取一个字符而无需循环就足够了(再次循环将得到一个无尽的字符);单独:如果用户在按“ enter”键之前根本不输入任何内容,则没有字符可以从std::cin中读取,我们仍在等待。

可以做的是阅读整行内容:

std::string s;
std::getline(std::cin, s);

这也将接受空行,因此也正是您想要的(注意:没有循环!)。

编辑(从评论中窃取;谢谢托马斯·马修斯):一种更优雅的方法是

std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

,因为它不会创建任何其他资源,否则它们以后都将被丢弃(std::string对象!)。

编辑2:

根据最后一个输入操作的类型,可能仍然有一个换行符(甚至更多的数据)被缓冲,例如。 G。在int n; std::cin >> n;之后。在这种情况下,您需要跳过尚未缓冲的输入。因此,您将需要忽略两次。

但是,如果最后一个输入操作已经消耗了换行符(例如std::getline –或者根本没有任何先前的输入操作),那么这将导致用户不得不按Enter键两次。因此,您需要检测以前发生了什么。

std::cin.rdbuf().in_avail()使您可以检测到还缓冲了多少个字符。因此,您可以:

if(std::cin.rdbuf().in_avail())
{
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
std::cout << "press enter" << std::endl;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

在某些系统(包括我的系统)上,尽管还缓冲了换行符,in_avail仍可以返回0! std::cin.sync_with_stdio(false);可以解决问题;您应该在第一次输入操作之前执行它。希望您不要使用C ++(流)和C(scanfprintf等)混合在一起的IO ...

答案 1 :(得分:0)

最简单的方法是使用getline()

cin >>忽略空格,包括换行符。 getline()将读取整行,包括换行符。但是,它不会将换行符复制到输出字符串。如果用户只是按下Enter键,而没有其他选择,那么您最终将得到一个空字符串。

因此,要获得所需的行为,您可以像这样构建循环:

string line;
while(true)
{
    cout << "(Press Enter to Continue...) " << endl;
    getline(cin, line);

    if(line == "")
        break;
}

答案 2 :(得分:0)

@阿空加瓜(Aconcagua)回答了您的问题,但这就是我想要添加的内容。

通常,为了处理计算机中某种特定类型的事件,我们通常遵循event-driven范式或event-callback。 这个想法是有一个事件循环,等待新事件进入系统。在这种情况下,键盘是一个事件,然后事件循环调用event-callbackevent-callback的作用是将输入值与某些条件进行比较,然后执行其他一些任务(这可能会更改程序的某些状态或通知用户)。

该想法是通过两种方式保持CPU繁忙。

  1. event-driven:在等待新事件的同时执行其他任务
  2. multithreading:系统中的多个线程。这种方法的缺点是位于data-race

玩得开心