cin.eof()功能

时间:2011-02-08 22:27:17

标签: c++ visual-c++ iostream

我理解cin.eof()测试流格式。在输入时,当输入错误时,不会到达字符的结尾。我在 MSV C ++ 2010 上对此进行了测试,并没有理解奇怪的结果。无论我给出什么输入,我都会收到程序中出现的格式错误消息。

#include <iostream>
using namespace std;

int main()
{
    int i;
    cin>> i;

    if(!cin.eof())
    {
        cout<< "\n Format Error \n";
    }
    else
    {
        cout<< "\n Correct Input \n";
    }

    getchar();
    return 0;
}

我预期的结果:

i =

的值
  1. 10 =&gt; 正确输入但输出为格式错误
  2. 12a =&gt; 格式错误
  3. 有人可以解释我哪里错了。感谢。

8 个答案:

答案 0 :(得分:17)

std::cin.eof()测试 文件结尾 (因此是eof),而不是错误。对于错误检查,请使用!std::cin.good(),内置转换运算符(if(std::cin))或布尔否定运算符(if(!std::cin))。

答案 1 :(得分:10)

使用以下方式直接测试流的状态:

while (cin >> i)
{
    ...
}

答案 2 :(得分:3)

对于要进入EOF状态的输入流,您必须实际尝试读取超过流的结尾。即仅仅到达流中的流末尾位置是不够的,有必要实际尝试读取一个字符到达结尾。此尝试将导致EOF状态被激活,这反过来将使cin.eof()返回true。

然而,在你的情况下,你不仅没有这样做,你(很可能)甚至没有达到流的末尾。如果您从键盘输入10,则可能按[Enter]键完成输入。这导致在输入流中添加换行符。因此,在这种情况下,您实际使用>>运算符解析的实际上是10\n序列。由于您从流中请求了int值,因此它只读取流中的数字字符,即它显示为10,但它会在\n处停止。 \n保留在流中。你永远不会读它。因此,显然,您的代码永远不会到达流中的文件结尾位置。在这种情况下,您必须要求cin.eof()成为true

答案 3 :(得分:2)

#include <iostream>

int main() {
  using namespace std;
  int i;
  if (cin >> i) {
    cout << "Extracted an int, but it is unknown if more input exists.\n";
    char c;
    if (cin.get(c)) {  // Or: cin >> c, depending on how you want to handle whitespace.
      cin.putback(c);
      cout << "More input exists.\n";
      if (c == '\n') {  // Doesn't work if you use cin >> c above.
        cout << "But this was at the end of this line.\n";
      }
    }
    else {
      cout << "No more input exists.\n";
    }
  }
  else {
    cout << "Format error.\n";
  }
  return 0;
}

另见Testing stream.good() or !stream.eof() reads last line twice

使用上述程序的示例会话,请注意输入行标有实际输出中不存在的注释:

$ your-program
12  # input
Extracted an int, but it is unknown if more input exists.
More input exists.
But this was at the end of this line.

$ your-program
12a  # input
Extracted an int, but it is unknown if more input exists.
More input exists.

$ echo -n 12 | your-program
Extracted an int, but it is unknown if more input exists.
No more input exists.

$ your-program
a  # input
Format error.

答案 4 :(得分:2)

假设您的输入是基于行的,我建议您使用std::getline()读取整行。获得该行后,您可以对其进行分析并确定其是否包含正确或错误的输入。将该行放入std::istringstream并执行以下操作:

修改:将!! iss更改为static_cast<bool>(iss)以与C ++ 0x兼容。

std::istringstream iss (line);
char ch;
long lval;
// read the input
iss >> lval;
// result variable will contain true if the input was correct and false otherwise
result
    // check that we have read a number of at least one digit length
    = static_cast<bool>(iss)
    // check that we cannot read anything beyond the value read above
    && ! (iss >> ch);

答案 5 :(得分:1)

添加到上一个答案: 在阅读完输入后(如10),您不会在文件结尾处,因为您可以轻松输入更多内容。系统如何知道你不会?

当读取第二个输入(12a)时,它会正确读取可以作为整数一部分的所有数字。字母'a'不能,因此留待以后输入。例如,您可以使用此代码

读取12a的所有部分

int i; char c;

cin&gt;&gt;我&gt;&gt; ℃;

答案 6 :(得分:1)

cin.eof()测试流是否已到达文件末尾,如果您键入类似Ctrl + C(在Windows上),或者输入已重定向到文件等,则会发生这种情况。

要测试输入是否包含整数而不是整数,您可以首先将输入输入到字符串中,然后使用字符串流进行转换。如果不再从中提取字符串流,则字符串流确实达到eof。

#include <iostream>
#include <sstream>
#include <string>

int main() {
    using namespace std;
    int i;
    string input;
    cin >> input; //or getline(cin, input)
    stringstream ss(input);
    if (ss >> i && ss.eof()) {  //if conversion succeeds and there's no more to get
        cout<< "\n Correct Input \n";
    }
    else {
        cout<< "\n Format Error \n";
    }

  return 0;
}

答案 7 :(得分:0)

EOF代表 e nd o f f ile。 std :: cin是标准输入。在正常情况下,标准输入永远不会到达终点:您可以随时输入更多内容。

此外,.eof()仅在输入操作因尝试读取文件末尾而失败时才返回true。该程序实际上无法告诉它是“文件末尾”;也就是说,它能够发现下一次读取数据的尝试失败的唯一方法就是实际进行尝试。