使用流运算符将具有整数值的类保存到二进制文件中>> /<<<

时间:2017-12-20 17:00:17

标签: c++ binary integer

我有一个非常简单的问题。我看到类似这样的类似问题,但我尝试的所有问题都不适用于我的案例。我试图将具有3个不同整数值的类保存到二进制文件中。我需要解决这个问题,即重载C ++流运算符"<<" /">>"。所以我的实际代码似乎在我的文件中将整数值保存为二进制,但当我尝试从二进制文件中加载它时,它只返回一个与原始值不同的整数值。
我的班级:

class Time{
public:
    int hour;
    int minute;
    int second;

};

将单个值保存到文件的方法。我用reinterpret_cast尝试了这个,但没有例如:(char *)$ time.hour

std::ostream& operator<<(std::ostream &os, Time &time){

    os.write(reinterpret_cast<const char *>(&time.hour),sizeof(int));
    os.write(reinterpret_cast<const char *>(&time.minute),sizeof(int));
    os.write(reinterpret_cast<const char *>(&time.second),sizeof(int));
    return os;
}

std::istream& operator >>(std::istream &is,Time &time){

    is.read((char*)&time.hour,sizeof(int));
    is.read((char*)&time.minute,sizeof(int));
    is.read((char*)&time.second,sizeof(int));
    return is;
}

我的代码测试功能的结果是1878006928 :

int main() {
    Time time;
    time.hour = 24;
    time.minute = 33;
    time.second = 10;
    std::ofstream os("test.txt", std::ios::binary | std::ios::out);
    os << time;
    Time time2;
    std::ifstream is("test.txt",std::ios::binary | std::ios::in);
    is >> time2;
    std::cout << time2.hour;

}

希望你能理解我的问题。

1 个答案:

答案 0 :(得分:0)

@ivaigult注意到你忘了std::flush你的ofstream。 为了完成我的回答,我已经使用一些注释修改了代码,这可能很有用。恕我直言,最重要的是避免写下这样的东西:

 os.write(reinterpret_cast<const char *>(&time.hour),sizeof(int));

这非常危险,因为如果您在time.hour 中修改Time,则必须记住以修改sizeof(int) - &gt; sizeof(new type)。如果你忘了你通常会得到内存腐败的错误,后来发现这些错误并不好玩!使用C ++ 11,您可以使用decltype(time.hour),这样可以:像:

os.write(reinterpret_cast<const char *>(&time.hour), sizeof(decltype(time.hour)));

这里没有进一步的addo是带有注释的修改后的工作c ++ 11代码:

#include <fstream>
#include <iostream>

class Time
{
 public:
  int hour;
  int minute;
  int second;

  // *** would allow you to access protected members (if any)
  //
  friend std::ostream &operator<<(std::ostream &os, Time &time);
  friend std::istream &operator>>(std::istream &is, Time &time);
};

std::ostream &operator<<(std::ostream &os, Time &time)
{

  // *** sizeof(in) -> sizeof(decltype(time.hour)
  // otherwise bug prone: if you modify the Time class, you have to remember to
  //                      modify this function too!
  os.write(reinterpret_cast<const char *>(&time.hour), sizeof(decltype(time.hour)));
  os.write(reinterpret_cast<const char *>(&time.minute), sizeof(decltype(time.minute)));
  os.write(reinterpret_cast<const char *>(&time.second), sizeof(decltype(time.second)));
  return os;
}

std::istream &operator>>(std::istream &is, Time &time)
{

  // *** ditto: bug prone
  // + be consistent: if you use reinterpret_cast before, use it also here
  // and not the C-style cast(char *)
  is.read(reinterpret_cast<char *>(&time.hour), sizeof(decltype(time.hour)));
  is.read(reinterpret_cast<char *>(&time.minute), sizeof(decltype(time.minute)));
  is.read(reinterpret_cast<char *>(&time.second), sizeof(decltype(time.second)));
  return is;
}

int main()
{
  Time time;
  time.hour = 24;
  time.minute = 33;
  time.second = 10;

  // *** std::ios::binary is enough, std::ios::out is redundant with
  //     std::_o_fstream
  std::ofstream os("test.txt", std::ios::binary);
  os << time;

  // os.close(); or at least a flush
  os.flush();

  Time time2;
  // *** ditto: std::ios::binary is enough
  std::ifstream is("test.txt", std::ios::binary);
  is >> time2;
  std::cout << time2.hour << " " << time2.minute << " " << time2.second;
}