暂停功能永远循环

And*_*nte -1 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();
}
Run Code Online (Sandbox Code Playgroud)

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

Aco*_*gua 6

在第一个:enter != '\n' || enter != '\r'是一个同义反复:即使enter 的字符等于一个也不能等于另一个。因此,其中一个测试必须为真...如果两个enter都不相等,则实际上您希望停留在循环中。

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

可以做的是阅读整行:

std::string s;
std::getline(std::cin, s);
Run Code Online (Sandbox Code Playgroud)

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

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

std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
Run Code Online (Sandbox Code Playgroud)

因为它不会创建任何其他资源(无论如何,该资源随后都将被丢弃std::string)。

编辑2:

根据上次输入操作的类型,可能仍会缓冲一个换行符(甚至更多的数据),例如之后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');
Run Code Online (Sandbox Code Playgroud)

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