【问题标题】:How eof() read the lines in the file?eof() 如何读取文件中的行?
【发布时间】:2020-07-19 03:40:37
【问题描述】:
#include <iostream>
#include <fstream>
using namespace std;

int main()
{
    ofstream files;
    files.open("FIRST.TXT");
    string abc;
    getline(cin, abc);
    files << abc;
    files.close();
    ifstream fin;
    fin.open("FIRST.TXT");
    ofstream fout;
    fout.open("SECOND.TXT");
    char word[30];
    while (!fin.eof())
    {
        fin >> word;
        if (word[0] == 'a' || word[0] == 'e' || word[0] == 'i' || word[0] == 'o' || word[0] == 'u')
            fout << word << " ";
        cout << word << endl;
    }
    fin.close();
    fout.close();   
}

此代码将以元音字母开头的单词存储在另一个文件中,而不是我们从中读取数据的文件中。

char word[30] 如何获取确切的单词,eof() 是否工作空间到空间?

为什么循环检查单词而不是字符,或者它检查空格后的第一个字符,如果是,为什么?

【问题讨论】:

标签: c++ file-handling eof


【解决方案1】:

while 循环中对 eof 的检查不起作用。您会在 SO 中找到大量页面来解释这一点。 Nate Eldredge 在上面的评论中给出了一个例子:Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?

此外,我建议使用更现代的 C++ 语言元素。这样一来,您就可以避免所有细节问题。

请看下面的例子:

#include <iostream>
#include <sstream> 
#include <string>
#include <algorithm>
#include <iterator>

std::istringstream testFile(R"(Lorem ipsum dolor sit amet, 
consetetur sadipscing elitr, sed diam nonumy eirmod tempor 
invidunt ut labore et dolore magna aliquyam erat, sed diam 
voluptua. At vero eos et accusam et justo duo dolores et ea 
rebum. Stet clita kasd gubergren, no sea takimata sanctus est 
)");

int main() {

    std::copy_if(std::istream_iterator<std::string>(testFile),{},
        std::ostream_iterator<std::string>(std::cout, "\n"),
        [](const std::string& s) { return (0x208222 >> (s[0] & 0x1f)) & 1; });

    return 0;
}

如您所见,整个任务可以通过一个copy_if() 语句完成。

而且,数据来自哪里并不重要。目前,我使用的是std::istringstream。但是,您也可以打开一个文件并将std::ifstream 变量放入std::istream_iterator。与输出相同。目前,我正在写信给std::cout。您也可以在此处放置一个开放的std::ofstream 变量。

所以,现在到std::copy_if()。请see here进行说明。 copy_if() 采用 2 个输入迭代器作为源的开始和结束,一个输出迭代器和一个条件。

istream_iterator 基本上会调用提取器operator&gt;&gt; 并从流中提取std::strings。它将被调用,直到文件结束(或发生错误)。结束迭代器由空大括号默认初始值设定项给出。如果你look here,你会看到默认构造函数等于结束迭代器。

为了写入数据,我们将使用std::ostream_iterator,它将所有复制的字符串写入输出流。

对于std::copy_if() 中的条件,我们使用 lambda,它检查字符串的第一个字符是否为元音。

检测元音的算法我已经详细描述了here

所以,很简单。只需要一个声明。

【讨论】:

  • std::bitset 会比那个 bithack 更现代,更不那么坚韧,你不觉得吗?
  • 是的,我同意。我想我在几十年前就用过这个,当时还没有 bitset。但是你说得对,我以后会把它改成bitset
猜你喜欢
  • 1970-01-01
  • 2016-08-13
  • 2013-01-06
  • 2015-06-21
  • 1970-01-01
  • 1970-01-01
  • 2013-08-02
  • 1970-01-01
  • 2017-07-16
相关资源
最近更新 更多