【问题标题】:std::getline(std::cin) setting failbitstd::getline(std::cin) 设置失败位
【发布时间】:2014-10-23 15:13:53
【问题描述】:

我不知道发生了什么,我用cin 尝试了各种事情,包括忽略参数和不考虑参数以及同步和各种事情。我想做的只是getline(cin, str)。如果有帮助的话,我会参加 Visual Studio Express 2013。

这是我的代码:

bool prompt(std::string &str)
{
    cout << "> ";
    if (cin) cout << endl << "Everything is ok" << endl;
    std::getline(std::cin, str);
    if (!cin) cout << "cin is failed" << endl;
    pause();
    return true;
}

编辑:删除了 cin.ignorecin.sync。错误仍然发生

程序现在输出“一切正常”和“cin 失败”。除了“cin 失败”位之后没有暂停。

有什么想法吗?非常感谢。

【问题讨论】:

  • cin.sync();的目的是什么?
  • @jrok 我不确定是否完全诚实。只是有人建议我尝试一下,然后把它扔在这里,以说明我已经尝试过所有被扔给我的东西。
  • 另外,如果cin.ignore(256,'\r˙); 的可用字符少于 256 个,它将阻塞并等待输入。我不得不问 - 你想在这里实现什么?
  • Can't reproduce,问题不在于你的程序
  • 我在这里缺少short, complete example

标签: c++ c++11


【解决方案1】:

我使用 Visual Studio Ultimate 2013 Update 3 编译了以下代码。 pause();声明被注释掉了,因为我不知道它是什么。

#include "stdafx.h"
#include <iostream>
#include <string>
#include <conio.h>

using namespace std;

bool prompt(std::string &str)
{
    cout << "> ";
    if (cin) cout << endl << "Everything is ok" << endl;
    std::getline(std::cin, str);
    if (!cin) cout << "cin is failed" << endl;
    // pause();
    return true;
}

int main()
{
    string strIn;
    prompt(strIn);
    cout << "Input: " << strIn << endl;
}

运行时,输出为

>
Everything is ok
Input Test.
Input: Input Test.

我没有看到故障位问题。 Visual Studio Express 2013 可能有问题?

来自http://www.cplusplus.com/reference/string/string/getline/

failbit:获得的输入无法解释为有效的文本 这种类型的对象的表示。在这种情况下,分配 保留调用前的参数和内部数据。 请注意,某些 eofbit 案例也会设置 failbit。

如果输入 Ctrl+Z 作为输入,会显示“cin is failed”:

>
Everything is ok
^Z
cin is failed
Input:

【讨论】:

  • 这与我前段时间发布的答案相同,似乎无论出于何种原因都不喜欢OP。
  • express 没有问题,这段代码在我的 express 安装中运行良好。
【解决方案2】:

这是真的

if(cin) 
  std::cout "everything is okay";

如果cin 设置了failbad 位,则不会打印该语句,但如果它设置了eof bit set,则不会打印:

bool prompt(std::string &str)
{
    cout << "> ";
    if (cin) cout << endl << "Everything is ok" << endl; // Will be printed
    std::getline(std::cin, str);
    if (!cin) cout << "cin is failed" << endl; // Will be printed
    return true;
}
int main()
{
    std::string obj;
    std::cin.setstate(std::ios::eofbit); // Simulate an eof/Ctrl^Z on Win read
    prompt(obj);
}

Reproducer

之前的操作可能未设置,这也在one of your previous topics 中进行了讨论。

为确保cin 处于有效状态,您应首先使用cin.clear(); 取消设置其状态位

bool prompt(std::string &str)
{
    cin.clear(); // Reset state bits
    cout << "> ";
    if (cin) cout << endl << "Everything is ok" << endl;
    std::getline(std::cin, str);
    if (!cin) cout << "cin is failed" << endl;
    return true;
}

如果您的代码仍然碰巧失败,请确保您实际上正在阅读有效的文本输入,并避免阅读 invalid characters

【讨论】:

  • 我逐字复制并粘贴了该代码,但代码仍然失败。我不知道无效字符会在哪里进入控制台,因为甚至无法输入任何内容,它会立即失败
  • 此时您可能应该发布完整的代码。我认为没有其他方法可以处理该错误。
  • 请通过运行“chcp”检查控制台代码页 (msdn.microsoft.com/en-us/library/windows/desktop/…)。我得到“活动代码页:437”。
  • 这是真的@Jake 你也应该检查一下
  • @Garland 也是一样的。
【解决方案3】:

我在eclipse上重现了这个问题:

#include <iostream>
#include <string>


using namespace std;

bool prompt(std::string &str)
{
    cout << "> ";
    if (cin) cout << endl << "Everything is ok" << endl;
    std::getline(std::cin, str);
    if (!cin) cout << "cin is failed" << endl;
    return true;
}

int main()
{
    string strIn;
    prompt(strIn);
    cout << "Input: " << strIn << endl;
}

现在你会得到输出:

> 
Everything is ok
cin is failed
Input:

每当您在 Eclipse 上终止正在运行的程序时。这意味着其他一些进程可能正在终止您正在运行的程序。

【讨论】:

    【解决方案4】:

    我能够通过几种不同的方法来模仿这些结果,所有这些方法都涉及一些重新定义 cin 或将 cin 设置为奇怪状态的特殊外观的奇怪事物。下面的代码会产生这个问题:

    #include <string>
    #include <iostream>
    using namespace std;
    
    bool prompt(std::string &str)
    {
        cout << "> ";
        if (cin) cout << endl << "Everything is ok" << endl;
        std::getline(std::cin, str);
        if (!cin) cout << "cin is failed" << endl;
        return true;
    }
    
    int main()
    {
        cin.setstate(ios::eofbit);
        string test;
        prompt(test);
    }
    

    该代码生成输出:

    >
    Everything is ok
    cin is failed
    

    此代码为 cin 设置了 eof 标志,这不会导致它失败,因此对 cin 的检查返回 true,但任何读取它的尝试都会立即失败。另一种方法涉及在其中更改 cin 的定义(或者在我的情况下,我复制了它,然后对其进行了修改并包含了副本)。这些是我能够想出的在 Visual Studio 2013 中生成您的函数所具有的输出的唯一方法。

    【讨论】:

      【解决方案5】:

      我发现了发生了什么。我真是太愚蠢了,我完全忘记了我一开始是如何分配控制台的。在我的主要功能中:

      if (AllocConsole())
      {
          freopen("CONOUT$", "wt", stdout);
          ShowWindow(GetConsoleWindow(), SW_SHOW);
      }
      

      我一直使用这个漂浮在互联网上的 sn-p。但是,我没有想到输入流尚未链接到控制台。我添加了这一行:

      freopen("CONIN$", "rt", stdin);

      这似乎成功了。

      【讨论】:

        猜你喜欢
        • 2011-10-12
        • 2020-03-14
        • 2015-11-17
        • 2012-04-01
        • 2017-08-29
        • 2021-08-17
        • 2020-10-20
        • 2021-03-24
        • 2011-06-12
        相关资源
        最近更新 更多