使用:同时(CIN>>x)和EOF

use of: while (cin >> x) and eof

本文关键字:gt EOF CIN 使用 同时      更新时间:2023-10-16

我不太确定我在这里的根本问题是如何工作的。我已经阅读了之前关于while(cin>>x(的一些帖子,但似乎没有什么能真正回答我的问题。我正在使用这个循环来读取一些文本数据:

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

但稍后在代码中,我尝试使用一个单词阅读:

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

但是上面的 while loop/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 流

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.

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

编辑2:为了完整性:使用cin.clear()的"成功率"将取决于实现。更可靠的解决方案是在程序的第一阶段使用不同的方式标记单词流的结束。人们可以使用单个"."或"!"或其他一些不应该出现在"单词"中的东西 - 或者更长的东西,例如"&&@&&",但这会使输入和记住输入15页变得困难。

当执行离开循环时

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

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

若要使流再次可用,必须通过调用 cin.clear(); 来重置错误标志

如果x我们知道第一个循环,但基本上:你读取所有可用的输入,然后尝试阅读更多内容,您会惊讶地发现失败。 相反的情况会让我感到惊讶。

真正的问题是:你想做什么? 基本上x的类型是什么,以及——我假设你是在假设cin是一个交互式设备,因为prompt - 如何确定第一个输入具有完成? 如果第一个循环由于"文件结束"而结束(用户在Unix下输入control-D,或在Windows下输入control-Z(,然后您不可能可靠地期望阅读更多内容。 重 置cin.clear()的错误状态可能有效;它会导致尝试从streambuf中阅读更多内容istream. 但它可能不会;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有其他类型,您也可能需要考虑类似的东西。

我使用了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)

乌班图:

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

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

感谢您的所有帮助(实际上是我的第一个堆栈溢出问题!

遇到尾行字符或换行符时,CIN将停止。因此,每次您输入内容并按回车键时,您都会提供一个""。while(cin>>x({} 应该用于连续读取没有 endline/'' 的输入。