我正在尝试了解如何正确地将数据更正为二进制文件。正在写入数据但是当重新读回来进行测试时,显然我没有正确地编写它。读取/写入数据如下。
无符号字符表示下一个字符串的长度,然后写入字符串,然后写入整数ID。 (或学生名student_id)。以下是printList函数,它将数据保存到文件中。
void printList(struct node * nptr, string filename){
ofstream myfile;
myfile.open( filename.c_str(), ios::binary );
while(nptr){
myfile.write( (char*) &nptr->data.len, sizeof( unsigned char ) );
myfile.write( (char*) nptr->data.name, len * sizeof(char) );
myfile.write( (char*) &nptr->data.id, sizeof(int) );
//myfile.write( (const char*) &nptr->data, sizeof( Student ) );
nptr = nptr->next;
}
myfile.close();
}
以下是学生结构,数据存储在链接列表中:
struct node{
Student data;
struct node* next;
};
//=== Student struct===//
struct Student{
unsigned char len;
char* name;
int id;
};
//====================//
这是我写的读取二进制文件的loadbin文件,我再次弄乱了一些东西,我已经阅读并观看了大量关于此的教程。我真的很难过。
unsigned char len;
char* name;
int id;
int main( int argc, char* argv[] )
{
if( argc > 1 )
{
ifstream f( argv[1] , ios::binary);
while( !f.eof() )
{
f.read( (char*) &len , sizeof( unsigned char ) );
if( f.eof() )
break;
name = new char[len+1];
name[len+1] = '\0';
f.read( (char*) name , len * sizeof( char ) );
f.read( (char*) &id , sizeof( int ) );
cout << (int)len << " " << name << " " << id
<< "\n";
}
}
else
cout << "\nToo few arguments.\n";
}
更多信息,我无法更改文件的读取方式。修复必须来自我写作时。我只是把它包括在内以防万一。
答案 0 :(得分:1)
对于 start,我甚至不确定这应该编译,除非你的某个地方有len
个变量,例如在你的上一个代码段中:
myfile.write( (char*) nptr->data.name, len * sizeof(char) ); // len, what len?
由于sizeof(char)
总是一个而且我更喜欢显式表达式,所以我将三个输出行重写为:
myfile.write ((const char *)(&(nptr->data.len)), 1);
myfile.write ((const char *)(nptr->data.name), nptr->data.len);
myfile.write ((const char *)(&(nptr->data.id)), sizeof(int));
一个完整的程序,显示如何使用它,类似的足够,它会有所帮助,但足够不同,以便你不能把它作为你自己的工作: - )
#include <iostream>
#include <fstream>
struct Student {
unsigned char len;
char *name;
int id;
};
struct node {
Student data;
struct node *next;
};
int main (void) {
// Create dummy list, two nodes.
node *temp = new node();
temp->data.len = 6;
temp->data.name = (char *)"diablo";
temp->data.id = 2;
temp->next = NULL;
node *shortList = new node();
shortList->data.len = 3;
shortList->data.name = (char *)"pax";
shortList->data.id = 1;
shortList->next = temp;
// Write it out.
std::ofstream myfile;
myfile.open ("xyzzy.bin", std::ios::binary);
node *curr = shortList;
while (curr != NULL) {
myfile.write ((const char *)(&(curr->data.len)), 1);
myfile.write ((const char *)(curr->data.name), curr->data.len);
myfile.write ((const char *)(&(curr->data.id)), sizeof(int));
curr = curr->next;
}
myfile.close ();
return 0;
}
如果您运行该程序然后执行十六进制转储,则得到:
addr +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f 0123456789abcdef
---- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- ----------------
0000 03 70 61 78 01 00 00 00 06 64 69 61 62 6c 6f 02 .pax.....diablo.
0010 00 00 00 ...
0013
我认为匹配你想要的格式。
答案 1 :(得分:0)
如果没有对文件内容的一些线索,很难调试,但要尽量确保事情绝对清楚。
而不是
myfile.write( (char*) &nptr->data.len, sizeof( unsigned char ) );
myfile.write( (char*) nptr->data.name, len * sizeof(char) );
myfile.write( (char*) &nptr->data.id, sizeof(int) );
写入错误的可能性较小(我挤出空格以保持行长):
myfile.write((char*)&nptr->data.len, sizeof(nptr->data.len) );
myfile.write((char*)nptr->data.name, nptr->data.len*sizeof(nptr->data.name[0]));
myfile.write((char*)&nptr->data.id, sizeof(nptr->data.id) );
并使用类似的表达式在读回数据时解压缩数据。在变量上使用sizeof比使用类型名称更强大。