2009-10-06 72 views
1

当代码完成时,为什么我会获得额外的迭代(额外的行打印)? EOF中是否需要额外的换行符?我宁愿不必添加额外/特殊字符来标记EOF。带有额外最终迭代的文件回显循环

#include <iostream> 
#include <fstream> 
#include <string> 
using namespace std; 

int main(){ 
    ifstream infile("dictionary.txt"); // one word per line 
    string text; 
    while(infile){ 
     infile >> text; 
     cout << text << endl; 
    } 
    infile.close(); 
    return 0; 
} 
+1

你能否证实“dictionary.txt”没有一个新的行末?因为你的代码似乎是直接读入,写出。 – Nasir 2009-10-06 20:38:17

+1

@ nr81:这是读取文件的标准反模式。因为在读取之后没有测试eof(使用操作符>>),那么最后一行将被打印两次。请参阅下面的回复,了解正确的读取文件模式。 – 2009-10-06 20:52:46

回答

6

尝试

while(infile>>text) cout << text << endl; 

代替。

+0

虽然条件真的引发了我的ha。。我不喜欢副作用 - 当然,除了那些特殊情况,我不这样做。无论如何,我出于各种原因抵制downvote,并最终决定upvote - 不仅仅是因为它简洁,简单,可靠和一个共同的标准库成语,每个人都应该明白。即使如此......认为自己咆哮着;-) – Steve314 2009-10-06 21:04:07

+0

谢谢,Steve314,我不介意被咆哮。 ;-)而且,说实话,当副作用是工作代码时,我确实喜欢副作用。 – 2009-10-06 21:07:16

3

随着你的条件,你检查流是否处于良好状态。然后你从流中读取,这可能会或可能不会成功。然后你输出文本的值。你应该做的是:

while(infile >> text){ 
    cout << text << endl; 
} 
3

在文件的结尾,infile仍可能评估为true,但一个字与infile >> text以下提取失败。即使它失败了,你仍然打印出一行。一个更好的办法来做到这一点是让while循环检查成功提取:

string text; 
ifstream infile("dictionary.txt"); // one word per line 
while (infile >> text) { 
    cout << text << endl; 
} 
infile.close(); 
6

的输入流不检测结束的文件,直到后您尝试读取过去吧。当您读取文件中的最后一个单词时,输入流仍然有效;在下一个循环中,infile >>文本尝试读取过去的EOF并失败,但下一行仍然执行。

循环应该是这样的:它试图写入输出之前

while (infile >> text) 
    cout << text << endl; 

这样EOF将被检测到。

+1

你已经包含了关于EOF的神奇单词。为了多样性+1 +1 – 2009-10-06 20:50:27

1

你已经得到了一些修正,但也许稍有不同的一个值得考虑:

#include <iterator> 
#include <iostream> 
#include <string> 
#include <fstream> 

using namespace std; // not really a good idea, but harmless enough for now. 

int main() { 
    ifstream infile("dictionary.txt"); 
    copy(istream_iterator<string>(infile), istream_iterator<string>(), 
     ostream_iterator<string>(cout, "\n")); 
    return 0; 
} 
+0

+1。不过,我认为在这种情况下它并不特别有趣,因为我怀疑这个想法是复制单词或将它们推送到另一个迭代器中。 – 2009-10-07 17:07:18