繁体   English   中英

使用迭代器正确读取和写入std :: vector到文件中

[英]Reading and writing a std::vector into a file correctly with iterators

我试图理解这里提供的答案,但我似乎无法使其发挥作用。

这是我尝试过的:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
#include <fstream>

int main()
{
    std::string path("numbersfile");

    std::vector<int> myVector{1,16,32,64};
    std::vector<int> newVector{};

    std::ofstream FILE(path,std::ios::out | std::ofstream::binary);
    std::copy(myVector.begin(),myVector.end(),std::ostreambuf_iterator<char>(FILE));

    std::ifstream INFILE(path,std::ios::in | std::ifstream::binary);
    std::istreambuf_iterator<char> iter(INFILE);
    //std::copy(iter.begin(),iter.end(),std::back_inserter(newVector)); //this doesn't compile
    std::copy(iter,std::istreambuf_iterator<char>{},std::back_inserter(newVector)); // this leaves newVector empty
}

最后一次copy后, newVector仍为空。 如何更新最后一个语句以填充newVector

在调用第二个copy时,文件尚未准备好读取。 (感谢Piotr Skotnicki在评论中的回答)

flush的调用允许程序工作:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
#include <fstream>

int main()
{
    std::string path("numbersfile");

    std::vector<int> myVector{1,16,32,64};
    std::vector<int> newVector{};

    std::ofstream FILE(path,std::ios::out | std::ofstream::binary);
    std::copy(myVector.begin(),myVector.end(),std::ostreambuf_iterator<char>(FILE));
    FILE.flush(); // required here

    std::ifstream INFILE(path,std::ios::in | std::ifstream::binary);
    std::istreambuf_iterator<char> iter(INFILE);
    //std::copy(iter.begin(),iter.end(),std::back_inserter(newVector)); //this doesn't compile
    std::copy(iter,std::istreambuf_iterator<char>{},std::back_inserter(newVector)); // this leaves newVector empty
    return 0;
}

创建ifstream时, ofstream仍在范围内。 如果已经调用了ofstream的析构函数,那么该文件也已经为ifstream做好了准备。 在以下程序中, ifstream会自动销毁:

#include <algorithm>
#include <fstream>
#include <iterator>
#include <vector>

std::string filename("numbersfile");

std::vector<double> myVector{1.342, 16.33, 32.1, 12364};

void write_vector_to_file(const std::vector<double>& myVector, std::string filename);
std::vector<double> read_vector_from_file(std::string filename);

int main()
{
    write_vector_to_file(myVector, filename);
    auto newVector{read_vector_from_file(filename)};
    return 0;
}

void write_vector_to_file(const std::vector<double>& myVector, std::string filename)
{
    std::ofstream ofs(filename, std::ios::out | std::ofstream::binary);
    std::ostream_iterator<double> osi{ofs," "};
    std::copy(myVector.begin(), myVector.end(), osi);
}

std::vector<double> read_vector_from_file(std::string filename)
{
    std::vector<double> newVector{};
    std::ifstream ifs(filename, std::ios::in | std::ifstream::binary);
    std::istream_iterator<double> iter{ifs};
    std::istream_iterator<double> end{};
    std::copy(iter, end, std::back_inserter(newVector));
    return newVector;
}

您的代码中存在许多缺陷:

  1. 你定义了一个名为FILE的变量, 这是很糟糕的坏事 FILE是已存在对象的名称,它与将vector实例命名为: std::vector<int>array{}相当。
    它不仅令人困惑,而且非常危险,因为它几乎可以肯定地导致命名冲突。 此外,所有国会大厦名称都应保留给宏

  2. 你永远不会检查文件是否实际打开,如果不是,编译器不会警告你,并且流不会给出任何失败的指示(除非明确检查)。 所以,你应该经常检查。 最简单的方法是使用流布尔运算符:
    if (!ifile) throw std::runtime_error("error opening file");

  3. 你写道,这不编译:

    std::copy(iter.begin(),iter.end(),std::back_inserter(newVector));

    为什么会这样? 迭代器本身没有beginend函数,与迭代器关联的对象具有这些方法。

  4. 在这里拼凑所有这些是您的代码的修改版本:

     { std::string path("numbersfile"); std::vector<int> myVector{ 1,16,32,64 }; std::vector<int> newVector{}; std::ofstream outfile(path, std::ios_base::binary); std::copy(myVector.begin(), myVector.end(), std::ostreambuf_iterator<char>(outfile)); outfile.close(); std::ifstream infile(path,std::ios_base::binary); std::istreambuf_iterator<char> iter(infile); std::copy(iter, std::istreambuf_iterator<char>(), std::back_inserter(newVector)); // this leaves newVector empty infile.close(); // close explicilty for consistency } 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM