2023年11月29日发(作者:)

[C++]c++中⼆进制⽂件的创建与使⽤

⼆进制⽂件和⽂本⽂件是不同的⽂件类型,因此在创建等⽅式也是不⼀样的

使⽤⽂件⽅式见下表:

"r"(只读) 为输⼊打开⼀个⽂本⽂件

"w"(只写) 为输出打开⼀个⽂本⽂件

"a"(追加) 为追加打开⼀个⽂本⽂件

"rb"(只读) 为输⼊打开⼀个⼆进制⽂件

"wb"(只写) 为输出打开⼀个⼆进制⽂件

"ab"(追加) 为追加打开⼀个⼆进制⽂件

"r+"(读写) 为读/写打开⼀个⽂本⽂件

"w+"(读写) 为读/写创建⼀个⽂本⽂件

"a+"(读写) 为读/写打开⼀个⽂本⽂件

"rb+"(读写) 为读/写打开⼀个⼆进制⽂件

"wb+"(读写) 为读/写创建⼀个⼆进制⽂件

"ab+"(读写) 为读/写打开⼀个⼆进制⽂件

void generateBin(string filename, int npattern ,int ninput, int noutput){

FILE* file;

file = fopen(filename.c_str(), "w");

if (file == NULL)

{

throw runtime_error("network: could not open " + string(filename) + " for writing");

}

fwrite(&npattern, sizeof(int), 1, file);

fwrite(&ninput, sizeof(int), 1, file);

fwrite(&noutput, sizeof(int), 1, file);

float * input = new float[ninput];

float * output = new float[noutput];

float range = 1;

for (int n = 0; n < npattern;n++){

for (int i = 0; i < ninput; i++){

input[i] = range * ((float)rand() / RAND_MAX - 0.5);

}

fwrite(input,sizeof(float),ninput,file);

for (int o = 0; o < noutput; o++){

if (file == NULL)

throw runtime_error("Cannot open file " + filename + " for reading");

int ok =

fread(&npatterns, sizeof(int), 1, file) &&

fread(&ninput, sizeof(int), 1, file) &&

fread(&noutput, sizeof(int), 1, file);

cout << npatterns << " " << ninput << " " << noutput << endl;

cout << "ninput is:" << ninput << endl;

cout << "noutput is:" << noutput << endl;

cout << "npatterns is:" << npatterns << endl;

for (int i = 0; i < npatterns; i++) {

cout << "load_patterns i:" << i << endl;

data_read = fread(inputs, sizeof(float), ninput, file);

cout << "need: " << ninput << " get: " << data_read << endl;

if (data_read != ((size_t)ninput)) {

cout << "Wrong file format " << endl;

fclose(file);

throw runtime_error("Wrong file format");

}

data_read = fread(targets, sizeof(float), noutput, file);

if (data_read != ((size_t)noutput)) {

cout << "Wrong file format " << endl;

fclose(file);

throw runtime_error("Wrong file format");

}

cout << "load_patterns i:" << i << endl;

}

delete inputs;

delete targets;

fclose(file);

}

上⾯两段程序,试图创建⼀个⼆进制⽂件,并且向其中写⼊data,并且再在其中读出⼆进制数据。

但是运⾏的结果是错误的,

data_read 的数量⼩于ninput,原因是因为使⽤了⽂本⽂件的创建⽅式,但是确使⽤了⼆进制⽂件的操作。应该改为如下的代码

void generateBin(string filename, int npattern ,int ninput, int noutput){

FILE* file;

file = fopen(filename.c_str(), "wb");

if (file == NULL)

{

throw runtime_error("network: could not open " + string(filename) + " for writing");

}

fwrite(&npattern, sizeof(int), 1, file);

fwrite(&ninput, sizeof(int), 1, file);

fwrite(&noutput, sizeof(int), 1, file);

float * input = new float[ninput];

float * output = new float[noutput];

float range = 1;

for (int n = 0; n < npattern;n++){

for (int i = 0; i < ninput; i++){

input[i] = range * ((float)rand() / RAND_MAX - 0.5);

}

fwrite(input,sizeof(float),ninput,file);

for (int o = 0; o < noutput; o++){

output[o] = range * ((float)rand() / RAND_MAX - 0.5);

}

fwrite(output, sizeof(float), noutput, file);

}

if (fclose(file) != 0) {

throw runtime_error("network: error on saving to " + string(filename));

}

delete input;

delete output;

}

void readdata(){

int ninput =0;

int noutput = 0;

int npatterns = 0;

size_t data_read = 0;

float* inputs = new float[ninput];

float* targets = new float[noutput];

string filename = "";

FILE *file = fopen(filename.c_str(), "rb");

if (file == NULL)

throw runtime_error("Cannot open file " + filename + " for reading");

int ok =

fread(&npatterns, sizeof(int), 1, file) &&

fread(&ninput, sizeof(int), 1, file) &&

fread(&noutput, sizeof(int), 1, file);

cout << npatterns << " " << ninput << " " << noutput << endl;

cout << "ninput is:" << ninput << endl;

cout << "noutput is:" << noutput << endl;

cout << "npatterns is:" << npatterns << endl;

for (int i = 0; i < npatterns; i++) {

cout << "load_patterns i:" << i << endl;

data_read = fread(inputs, sizeof(float), ninput, file);

cout << "need: " << ninput << " get: " << data_read << endl;

if (data_read != ((size_t)ninput)) {

cout << "Wrong file format " << endl;

fclose(file);

throw runtime_error("Wrong file format");

}

data_read = fread(targets, sizeof(float), noutput, file);

if (data_read != ((size_t)noutput)) {

cout << "Wrong file format " << endl;

fclose(file);

throw runtime_error("Wrong file format");

}

cout << "load_patterns i:" << i << endl;

}

delete inputs;

delete targets;

fclose(file);

}