使用:while(cin>> x)和eof

时间:2013-07-01 12:10:24

标签: c++

我不太确定我认为我的根本问题是什么。我已经阅读了之前的一些帖子(cin>> x),但似乎没有什么能回答我的问题。 我正在使用此循环读取一些文本数据:

while (cin >> x){
    searchText.push_back(x);
}

但后来我在代码中试图用一个单词来阅读:

cout << "Please enter your target word: ";
string targetWord;
cin >> targetWord;

但上面的while循环/ eof似乎破坏了第二个代码片段(如果我将第二个代码片段移到它上面,一切正常,但显然这不是我想要做的)

修改的 为清晰起见,这是完整的代码:

int main()
{
// ask for the target word
//   cout << "Please enter your target word: ";
//   string targetWord;
//   cin >> targetWord;

   // ask for and read the search text
   cout <<  "Enter the complete search text, "
            "followed by end-of-file: ";
   vector<string> searchText;
   string x;
   while (cin >> x){
      searchText.push_back(x);
   }

   // check that some text was entered
   typedef vector<string>::size_type vec_sz;
   vec_sz size = searchText.size();
   if (size == 0){
      cout << endl <<   "You must enter some text. "
                        "Please try again." << endl;
      return 1;
   }

// ask for the target word
   cin.clear();
   cout << "";
   cout << "Please enter your target word: ";
   string targetWord;
   cin >> targetWord;


   int count = 0;
   for (int i=0; i<size; ++i){
      if (targetWord == searchText[i]){
      count++;
      }
   }

   cout  << "The target word [" << targetWord << "] was "
            "in the search text " << count << " times." << endl;

   return 0;
}

我只是想从用户那里接收一些文字......然后是一个搜索词,看看这个词出现在输入文本中的次数(非常简单!)

我知道我可以采用不同的方式,但这里的问题更多的是关于如何在之前有一个EOF之后再次使用cout / cin流

5 个答案:

答案 0 :(得分:4)

cin(或任何其他std::stream)命中文件末尾时,它会设置一个状态以指示已发生这种情况。

要重置此状态,您需要调用cin.clear();,这将清除任何“错误”状态,并确保流“好”再次使用。如果您正在从文件中读取并希望从头重新开始,这也适用。

编辑:我刚拿上面张贴的代码,然后在我的机器上运行,在顶部添加

#include <iostream>
#include <vector>

using namespace std;

以下是编译和运行:

$ g++ -Wall words.cpp 
words.cpp: In function ‘int main()’:
words.cpp:40:20: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
$ ./a.out
Enter the complete search text, followed by end-of-file: aa bb cc [CTRL-D]
Please enter your target word: aa
The target word [aa] was in the search text 1 times.

这是我期望看到的......

Edit2:为了完整性:使用cin.clear()的“成功率”取决于实现。更可靠的解决方案是使用不同的方式在程序的第一阶段标记单词流的结尾。可以使用单个"."或“!”或者其他一些不应该出现在“单词”中的东西 - 或者更长的东西,例如"&&@&&",但是当输入15页时很难输入并记住。

答案 1 :(得分:2)

执行离开循环时

while (cin >> x){
    searchText.push_back(x);
}

它是这样做的,因为cin的“测试”返回了false,换句话说,已在流上设置了failbit和/或badbit。在这种情况下,任何进一步尝试从流中读取的操作都将失败,即targetWord将保留为空。

要使流再次可用,您必须通过调用cin.clear();

重置错误标志

答案 2 :(得分:2)

如果我们知道x的类型,那将会有所帮助 第一个循环,但基本上:你读取所有可用的输入, 然后尝试阅读更多内容,你会惊讶于它 失败。相反会让我感到惊讶。

真正的问题是:你想做什么?基本上, 什么是x的类型,而且 - 我假设你是 假设cin是一个交互设备,因为 提示 - 如何确定第一个输入 完了吗?如果第一个循环因“文件结束”而结束(用户 在Unix下输入control-D,或在Windows下输入control-Z) 你无法可靠地期待阅读更多内容。重置 cin.clear() 的错误状态可能有效;它会导致 istream试图从streambuf中读取更多内容。但它 也许不会; istream下面有任意数量的图层 无论出于何种原因,它可能记住了文件的结尾。 所以你必须找到一些不同的识别方法 端。

从猜测的名称中猜测:如果你正在尝试 要阅读单词列表,我会使用std::getline,空白 列表末尾的行。所以第一个循环将成为:

while ( std::getline( std::cin, x ) && x != "" ) {
    searchText.push_back( x );
}
if ( ! std::cin ) {
    //  Something really bad has happened...
}

或者,您可能想要分解白色线条 空格,每行允许多个单词(并忽略任何单词) 行中额外的空白区域:

std::string line;
while ( std::getline( std::cin, x ) && x != "" ) {
    std::istringstream l( line );
    while ( l >> x ) {
        searchText.push_back( x );
    }
}
if ( ! std::cin ) //  ...

即使x有其他类型,您也可以考虑 这些方面的东西。

答案 3 :(得分:0)

我使用了cin.clear()并且在我的mac设置上它似乎没有清除EOF但是在ubuntu设置上它确实清除了流

苹果:

(Canopy 32bit) joes-imac:chap3 joe$ g++ --version
i686-apple-darwin11-llvm-g++-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)

Ubuntu的:

joe@joe-HPlaptop:~$ g++ --version
g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
Copyright (C) 2011 Free Software Foundation, Inc.

我很高兴接受它只是编译器差异并完成/关闭问题(真的是一个愚蠢的小家伙!)

感谢所有的帮助(实际上我的第一个stackoverflow问题!)

答案 4 :(得分:0)

cin在遇到换行符或换行符时将停止。因此,每次您输入内容并按Enter时,您都会输入一个'\ n'。 while(cin >> x){}应该用于连续读取输入,而没有结束符/'\ n'。