fstream 的奇怪问题。不能存储成员变量具有特定值的对象
Weird problem with fstream. Cannot store objects with member variables having a certain value
当我尝试存储一个包含任何值为 13 或 26 或 7 的元素的对象,然后尝试读取该文件时,它只会给出垃圾值。对于 1、64、78(随机值)等其他值不会发生这种情况。
我分别使用了 ofstream
和 ifstream
以保持代码简单。我使用的是旧编译器(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;
};
当我尝试存储一个包含任何值为 13 或 26 或 7 的元素的对象,然后尝试读取该文件时,它只会给出垃圾值。对于 1、64、78(随机值)等其他值不会发生这种情况。
我分别使用了 ofstream
和 ifstream
以保持代码简单。我使用的是旧编译器(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;
};