使用迭代器,ifstream,ofstream意图完成它的方式

Edo*_*doz 4 c++ file-io iterator fstream coding-style

我有一个包含一堆单词的txt文件,每行一个.我需要读取这个文件,并把每个单词的列表,然后用户就可以修改此列表编辑完成后,程序会写一个新的文件修改的列表.

因为它是c ++的对象,我将有两个类,一个用于读/写文件,另一个用于编辑/混淆列表和用户.

考虑到这种方法,这是我在第一节课中的阅读功能:

bool FileMgr::readToList(list<string> &l)
{
if(!input.is_open())
    return false;

string line;
while(!input.eof())
{
    getline(input, line);
    l.push_back(line);
}
return true;
}
Run Code Online (Sandbox Code Playgroud)

请记住:输入是在构造函数中打开的.问题:是否有一种不那么多余的方法可以从istream中获取该死的线并将其推回l?(中间没有'字符串').除了问题,这个功能似乎正常.

现在输出功能:

 bool FileMgr::writeFromList(list<string>::iterator begin, list<string>::iterator end)
{
    ofstream output;
    output.open("output.txt");
    while(begin != end)
    {
        output << *begin << "\n";
        begin++;
    }
    output.close();
    return true;
}
Run Code Online (Sandbox Code Playgroud)

这是我主要的一部分:

    FileMgr file;
list<string> words;
file.readToList(words);
cout << words.front() << words.back();
list<string>::iterator begin = words.begin();
list<string>::iterator end = words.end();
file.writeFromList(begin, end);
Run Code Online (Sandbox Code Playgroud)

感谢您的帮助,这两个功能现在都有效.现在关于样式,这是实现这两个功能的好方法吗?getline(输入,线)部分我真的不喜欢,任何人都有更好的主意?

Jam*_*lis 7

如上所述,您的输入循环不正确.读取操作到达之后eof设置该标志,因此您可能会多次通过循环.此外,您无法检查和标记.有关标志,它们的含义以及如何正确编写输入循环的更多信息,请参阅Stack Overflow C++ FAQ问题标记的语义.eofbadfailbasic_ios

你的循环readToList应该如下所示:

std::string line;
while (std::getline(input, line))
{
    l.push_back(line);
}
Run Code Online (Sandbox Code Playgroud)

有了更多的C++方法,请参阅Jerry Coffin对如何cin在C++中逐行迭代的回答 他的第一个解决方案非常简单,应该让你很好地了解这种东西在惯用的STL风格的C++中的表现.

对于您的writeFromList功能,正如Tomalak解释的那样,您需要使用两个迭代器.在C++中使用迭代器时,几乎总是必须成对使用它们:一个指向范围的开头,一个指向范围的结尾.通常也可以使用模板参数作为迭代器类型,以便可以将不同类型的迭代器传递给函数; 这允许您根据需要交换不同的容器.

您不需要显式调用output.close():它由std::ofstream析构函数自动调用.

您可以使用std::copywith std::ostream_iterator将输出循环转换为单行:

template <typename ForwardIterator>
bool FileMgr::writeFromList(ForwardIterator first, ForwardIterator last)
{
    std::ofstream output("output.txt");

    std::copy(first, last, std::ostream_iterator<std::string>(output, ""));
}
Run Code Online (Sandbox Code Playgroud)

  • @Tomalak:我发现`line`代理非常有用. (2认同)