【问题标题】:Ways to write a vector of a class to a file将类的向量写入文件的方法
【发布时间】:2013-10-03 06:02:09
【问题描述】:

我不知道该怎么说,所以我会尝试将它放入代码中。 (这有很多错误我知道它不会编译它只是为了显示我想要做的事情,因为我无法用语言表达)

    using namespace std; //for correctness sake
    class foo {
    public:
        foo(int a=0, int n=0);
        void stuff(int a);
        void function(int n);
        const int get_function() {return n;}
        const int get_stuff(){return a;}
    private: 
       int n, a;
    };
    struct Store{
        public: get_foo(){return vector<f.foo>;} //I'm not too sure of the syntax here but you get the idea
    private: 
        foo f;

    }

基本上,我想获取类 foo 中返回的所有信息,并将其格式化输出到文件中。问题是,我需要在文件中制作其中的许多内容,并且它必须能够读回它才能使其有价值。 所以只是将每个连续的 foo 类附加到文件中是行不通的(至少我不明白如何)。

我尝试使用ostream 重载&lt;&lt; 运算符,但我不知道如何调用它来将其写入文件。欢迎任何建议!谢谢。

【问题讨论】:

  • 注意:const get_function() {return n;} 不是符合标准的 C++。该语言需要所有声明的类型说明符。这(以及get_stuff())应该用int 声明。自行决定您是否认为const 有必要(不是)。
  • @WhozCraig 你说得对,我忘记了函数类型,我使用了 const,因为这是我在课堂上看到的示例。
  • 我高度怀疑声明应该是int get_function() const { return n; },因为该成员没有修改对象的要求。

标签: c++ class file-io constructor struct


【解决方案1】:

我觉得你的Store应该是这样的:

struct Store
{
public:
    std::vector<foo> get_foo()
    {
       return f;
    }

private: 
    std::vector<foo> f;
};

要重载&lt;&lt;std::ostream

std::ostream& operator<<(std::ostream& out, const Store& f)
{
  for (auto &x : f.get_foo())
    out << x.get_function() << ", " << x.get_stuff() << "\n";

  return out;
}

//Without auto

std::ostream& operator<<(std::ostream& out, const Store& f)
{
  std::vector<foo> q = f;
  for (int i=0; i<q.size(); i++)
    out << q[i].get_function() << ", " << q[i].get_stuff() << "\n";

  return out;
}

【讨论】:

  • 感谢您的回复,您能向我解释一下 x 吗?我很困惑为什么它是 x.get_function 而不是 foo 类。抱歉,我不熟悉 auto 和几个 c++11 功能在这些情况下的工作原理。
  • @M M. 啊谢谢,我想我知道它现在在做什么了。它基本上浓缩了迭代(可能比实际简单得多)。在这种情况下使用 auto 与增加 i 以在向量中移动相比有什么优势吗?
  • @Shilaly:它的语法糖。使代码更小、更清晰、更通用。
【解决方案2】:

你的代码有很多地方有问题。

很明显,您从未读过任何 C++ 书籍,只是在尝试编译器。

不要那样做。由于许多独立的原因,C++ 确实是世界上最糟糕的语言。

不管你有多聪明。

实际上聪明在某些领域是个问题,因为许多 C++ 规则不是连贯逻辑设计的结果,而是历史演变和委员会决定的结果。即使是哈里·谢顿也无法正确预见委员会会做出什么决定,你无法推断历史。

只需选择good book 并从头到尾阅读。没有其他明智的方式来学习 C++。

关于将结构写入文件,该主题通常称为“序列化”,并处理将活动对象转换为死字节序列(写入文件或通过网络发送)和反之的稍微更普遍的问题将字节序列转换回活动对象的问题“反序列化”(在同一系统上、在另一个相同系统上,甚至在不同系统上)。

这个问题有很多方面,例如,如果您关心系统之间的可移植性、速度、字节序列的大小、重新加载字节序列的能力,这些字节序列在您的类略有不同时保存回来,因为您改进了程序(版本控制)。

您可以做的最简单的事情就是将 fwrite 写入文件,但这在 C++ 中通常是无稽之谈,即使在技术上可行的情况下,出于多种原因也是一种糟糕的方式。例如,您不能直接fwrite std::vector 对象并希望将其读回。

【讨论】:

  • 是的,我知道代码不会编译,这不是我要编译的,如果我能用文字说的话,我不会写任何代码。我的问题中代码的重点不是完美,而是要可视化我正在尝试对我的课程做什么。我想用 c++ 来做这件事,因为我正在尝试学习 c++。
  • 1000% 同意上述说法。 @Shilaly - 即使您觉得看书很无聊,您也可以在互联网上找到很多示例。其中一些甚至会编译。
  • @SChepurin 好吧,不管你信不信,这不是我的第一选择。我对“将结构向量写入文件”进行了多次搜索,但找不到任何接近适用的地方。如果您能指出我明显错过的一些内容,那将不胜感激。另外,附带说明一下,您在 Stroustrup 的书中找到的许多代码都无法编译。我完全理解我想要做什么的想法,语法让我感到困惑。
  • @Shilaly - 实现起来并不像看起来那么容易,有一些库只是为此目的而创建的(例如在 Boost 中)。至于问题,看看其他人的尝试-stackoverflow.com/questions/709297/…
【解决方案3】:

我认为你需要这样的东西:

template<typename T>
std::ostream& operator << (std::ostream& out, const std::vector<T*>& elements)
{
  for (size_t i = 0; i < elements.size(); i++)
    out << elements[i] << ", ";
  return out << std::endl;
}

【讨论】:

  • 谢谢,我还没有使用模板,所以我会研究模板并尝试你的建议。您是否特别推荐任何参考资料,或者 Google 搜索就足够了?
猜你喜欢
  • 2013-07-17
  • 2016-02-29
  • 2021-03-20
  • 2020-12-17
  • 2016-03-14
  • 1970-01-01
  • 1970-01-01
  • 2019-10-27
  • 1970-01-01
相关资源
最近更新 更多