c++ - C++ 中 EOF 的无限循环

标签 c++ eof cin std

此代码大部分按预期工作,提示用户输入单个字符,执行相关操作,提示用户按回车键,然后重复。但是,当我在提示符下输入 ^D (EOF) 时,出现死循环。我正在通过 std::cin.clear() 清除错误状态并调用 std::cin.ignore(...) 来清除缓冲区。什么可能导致无限循环?

#include <iostream>
#include <limits>

void wait()
{
    std::cout << std::endl << "press enter to continue.";
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    std::cin.clear();
    std::cin.get();
}

int main()
{
    char response;

    while (true)
    {
        std::cout << "enter a character at the prompt." << std::endl << "> ";
        std::cin >> response;
        switch (response)
        {
            case 'q':
                exit(0);
                break;
        }
        wait();
    }
}

如果重要的话,我正在 Mac OS X 终端中运行它。


更新:我在这里真正想问的是,当用户在提示符下输入 EOF (^D) 时,我如何 (a) 检测它并 ( b) 重置流,以便用户可以继续输入数据。

以下示例与上面的代码不同,但说明了在检测到 ^D 后清除流并继续从该流读取的相同原理.

> a
you entered: a
> b
you entered: b
> ^D
you entered EOF
> c
you entered: c
...

最佳答案

在调用格式化提取操作后,您应该始终检查是否设置了流的任何失败标志,在您的示例中,您正在检查 response不检查是否response被正确提取。

此外,您正在使用 std::endl在您的提示输出中没有意义的地方。 std::endl版画 \n然后刷新缓冲区,但是您随后会立即打印更多字符,因此刷新是多余的。作为cincout是(通常)tied,为 std::cin 调用输入函数会导致std::cout在任何情况下都要冲洗,所以你也可以放一个 \n进入您的提示字符串并节省冗长的额外<<运营商。

为什么不制作一个提示函数来打印提示、检索输入并返回对流的引用,以便您可以使用通常的流到 bool 类型转换来测试它是否成功。

这样你就可以摆脱 while true 和显式中断。

std::istream& prompt_for_input( std::istream& in, std::ostream& out, char& response )
{
    out << "enter a character at the prompt.\n> ";
    in >> response;
    return in;
}

int main()
{
    char response;

    while ( prompt_for_input( std::cin, std::cout, response ) && response != 'q' )
    {
        wait();
    }
}

关于c++ - C++ 中 EOF 的无限循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1598514/

相关文章:

c++ - 为什么我可以为字符串重载 istream 的 operator>>?

签名后的 C++ 参数声明

c++ - C++中set_intersection可以和hash_set一起使用吗?

c++ - 为什么循环是无限的?

c++ - 如何从管道传输到标准输入的文件获取输入

c++ - 从 cin 获取 C++ 结构中多个枚举的输入

c# - 从 32 位更改为 64 位

c# - 无法使用iTextSharp读取一些PDF文件

c - 如何在 Windows 中使用 Ctrl+D 结束一个 c 程序?

c++ - 当用户输入错误的输入时,从 cin 中清除整行而不是一次清除一个字符