为什么 fwrite / fread 不像 56.806201550387598?
Why do fwrite / fread not like 56.806201550387598?
我正在尝试将一个结构保存到一个文件中,然后在另一个程序中再次读取它。
我以前从来没有遇到过这个问题,但至少据我所知,我从未尝试过将值 56.806201550387598
的双精度变量写入文件。并不是说我不知道为什么这个数字会造成任何问题,但是每当我尝试将包含此值的结构写入文件时,该字段和在它之后声明的任何字段都只能从结构中读出初始化值宣言.
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
typedef struct statsSet{
int pathCount = 0;
double vMinMean = 0;
int imgsFound = 0;
int minWidth = INT_MAX;
int maxWidth = 0;
}statsSet;
void wrightToFile(statsSet sSet){
FILE* of = fopen ("imgStats2.dat", "w");
fwrite (&sSet, sizeof(statsSet), 1, of);
fclose (of);
}
statsSet readFromFile(){
statsSet statReadIn;
FILE *ifl = fopen ("imgStats2.dat" , "r");
fread(&statReadIn, sizeof(statsSet), 1, ifl);
fclose (ifl);
return statReadIn;
}
void pr(statsSet statReadIn){
cout << "pathCount: " << statReadIn.pathCount << "\n";
cout << "vMinMean: " << statReadIn.vMinMean<< "\n";
cout << "imgsFound: " << statReadIn.imgsFound<< "\n";
cout << "minWidth: " << statReadIn.minWidth<< "\n";
cout << "maxWidth: " << statReadIn.maxWidth<< "\n";
cout << "--------\n";
}
int main( int argc, char** argv ){
statsSet statTest;
statsSet statReadIn;
statTest.pathCount = 129;
statTest.imgsFound = 129;
statTest.minWidth = 488;
statTest.maxWidth = 501;
statTest.vMinMean = 56.806201550387591; // OK
wrightToFile(statTest);
statReadIn = readFromFile();
pr(statReadIn);
statTest.vMinMean = 56.806201550387598; //breaks
wrightToFile(statTest);
statReadIn = readFromFile();
pr(statReadIn);
statTest.vMinMean = 56.806201550387605; // OK
wrightToFile(statTest);
statReadIn = readFromFile();
pr(statReadIn);
}
输出:
pathCount: 129
vMinMean: 56.8062
imgsFound: 129
minWidth: 488
maxWidth: 501
--------
pathCount: 129
vMinMean: 0
imgsFound: 0
minWidth: 2147483647
maxWidth: 0
--------
pathCount: 129
vMinMean: 56.8062
imgsFound: 129
minWidth: 488
maxWidth: 501
--------
我做错了什么?
我正在使用 Windows 10、Visual Studio 代码和 MinGW-w64。
使用写入二进制模式。对于二进制数据,文本模式将非常随机。
FILE* of = fopen ("imgStats2.dat", "wb");
和
FILE *ifl = fopen ("imgStats2.dat" , "rb");
我正在尝试将一个结构保存到一个文件中,然后在另一个程序中再次读取它。
我以前从来没有遇到过这个问题,但至少据我所知,我从未尝试过将值 56.806201550387598
的双精度变量写入文件。并不是说我不知道为什么这个数字会造成任何问题,但是每当我尝试将包含此值的结构写入文件时,该字段和在它之后声明的任何字段都只能从结构中读出初始化值宣言.
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
typedef struct statsSet{
int pathCount = 0;
double vMinMean = 0;
int imgsFound = 0;
int minWidth = INT_MAX;
int maxWidth = 0;
}statsSet;
void wrightToFile(statsSet sSet){
FILE* of = fopen ("imgStats2.dat", "w");
fwrite (&sSet, sizeof(statsSet), 1, of);
fclose (of);
}
statsSet readFromFile(){
statsSet statReadIn;
FILE *ifl = fopen ("imgStats2.dat" , "r");
fread(&statReadIn, sizeof(statsSet), 1, ifl);
fclose (ifl);
return statReadIn;
}
void pr(statsSet statReadIn){
cout << "pathCount: " << statReadIn.pathCount << "\n";
cout << "vMinMean: " << statReadIn.vMinMean<< "\n";
cout << "imgsFound: " << statReadIn.imgsFound<< "\n";
cout << "minWidth: " << statReadIn.minWidth<< "\n";
cout << "maxWidth: " << statReadIn.maxWidth<< "\n";
cout << "--------\n";
}
int main( int argc, char** argv ){
statsSet statTest;
statsSet statReadIn;
statTest.pathCount = 129;
statTest.imgsFound = 129;
statTest.minWidth = 488;
statTest.maxWidth = 501;
statTest.vMinMean = 56.806201550387591; // OK
wrightToFile(statTest);
statReadIn = readFromFile();
pr(statReadIn);
statTest.vMinMean = 56.806201550387598; //breaks
wrightToFile(statTest);
statReadIn = readFromFile();
pr(statReadIn);
statTest.vMinMean = 56.806201550387605; // OK
wrightToFile(statTest);
statReadIn = readFromFile();
pr(statReadIn);
}
输出:
pathCount: 129
vMinMean: 56.8062
imgsFound: 129
minWidth: 488
maxWidth: 501
--------
pathCount: 129
vMinMean: 0
imgsFound: 0
minWidth: 2147483647
maxWidth: 0
--------
pathCount: 129
vMinMean: 56.8062
imgsFound: 129
minWidth: 488
maxWidth: 501
--------
我做错了什么?
我正在使用 Windows 10、Visual Studio 代码和 MinGW-w64。
使用写入二进制模式。对于二进制数据,文本模式将非常随机。
FILE* of = fopen ("imgStats2.dat", "wb");
和
FILE *ifl = fopen ("imgStats2.dat" , "rb");