fstream 的奇怪问题。不能存储成员变量具有特定值的对象

Weird problem with fstream. Cannot store objects with member variables having a certain value

当我尝试存储一个包含任何值为 13 或 26 或 7 的元素的对象,然后尝试读取该文件时,它只会给出垃圾值。对于 1、64、78(随机值)等其他值不会发生这种情况。

我分别使用了 ofstreamifstream 以保持代码简单。我使用的是旧编译器(Borland C++),但我的朋友们没有遇到过这个错误。

#include <iostream.h>
#include <conio.h>
#include <fstream.h>

class xyz
{
  public:
    int x;
};

void main()
{
    xyz a;
    a.x = 45; // replace by 45 or 78 it works. Replace by 13, 26 it shows garbage values.

    ofstream of;
    of.open("file.dat", ios::out||ios::binary);
    of.write((char*)&a, sizeof(a));
    of.close();

    xyz b;

    ifstream sf;
    sf.open("file.dat", ios::in||ios::binary);
    sf.read((char*)&b, sizeof(b));
    sf.close();

    cout<<b.x;
    getch();
}

当前输出将为 45,但如果将其替换为 13 或 26,则会打印垃圾值。

sf.open("file.dat", ios::in||ios::binary);

|| 并不像您认为的那样。在这里,您需要使用按位或运算符|,而不是||,后者是逻辑运算符。

因此,由于这个错误,您的文件实际上是以文本模式打开的,而不是您预期的二进制模式。

您的代码将二进制八位字节 13 和 26 写入文件并读回。由于其历史遗留问题,八位字节 13 和 26 在 Microsoft Windows 的文本文件中具有特殊含义。您的代码也无法检查来自 read() and/or 输入流状态的 return 值,这将使您能够检测到此错误。

这是因为您的代码包含问题,最明显的是您尝试使用 ||(logical/boolean OR)而不是 |(按位或)进行按位或用来像你一样把旗帜加在一起。

其他需要注意的事项(虽然我不确定它们是问题的直接根源): - 调用标准元素时忘记使用 std:: - main 总是需要 return int

下次键入,启用更多编译器标志以帮助查找代码中的问题。 我不知道 turbo-c++ 但在 g++ 中你可以添加 -Wall -Wextra 以获得更多警告。 还有更多可以启用的功能!

这是我提到的几处更改后的代码

#include <fstream>
#include <iostream>

class xyz
{
public:
  int x;
};

int
main()
{

  xyz a;
  a.x = 45;

  std::ofstream of;
  of.open("file.dat", std::ios::out | std::ios::binary);
  of.write((char*)&a, sizeof(a));
  of.close();

  xyz b;

  std::ifstream sf;
  sf.open("file.dat", std::ios::in | std::ios::binary);
  sf.read((char*)&b, sizeof(b));
  sf.close();

  std::cout << b.x;
}

请注意,如果您无法访问 "recent" 编译器(我假设您被困在一个版本上),则有几个在线编译器可以让您编译代码: - https://wandbox.org - https://gcc.godbolt.org/ - 等等

您的编码实际上不正确这里是基于您的代码的解释:

#include<iostream>
#include<fstream>
#include<ios>
using namespace std;
struct xyz{
    int x;
};
int main(){

    xyz a, b;
    a.x=134;

    fstream of;
    of.open("file.dat"s, ios::out|ios::binary); // bitwise or
    of.write((const char*)&a, sizeof(a));
    of.close();


    ifstream sf;
    sf.open("file.dat"s, ios::in|ios::binary);
    sf.read((char*)&b, sizeof(b));
    sf.close();

    cout<<b.x<<endl;
    return 0;


};