如果你需要我在下面发布的任何信息,请告诉我,这样我就可以更新帖子了。
我保存到文件中的是下面结构的字段。因为文件一开始没有注册,所以我必须通过将标志设置为0来初始化它。
struct pedia
{
int code;
char descr[50];
int TM;
int pos;
int flag;
};
我打开了一个文件,在那里我可以使用进行写/读
if((fp=fopen(name,"wb+"))==NULL)
用户给出了可以保存在文件中的最大注册数
稍后,我在一个函数中发送指针fp,以初始化像这样的文件
void initialization2(FILE *f,int size)
{
int i;
struct pedia *ptr;
ptr=(struct pedia *)malloc(sizeof(struct pedia));
for(i=0;i<size;i++)
{
ptr->code=i;
strcpy(ptr->descr," ");
ptr->TM=-1;
ptr->pos=-1;
ptr->flag=0;
fwrite(ptr,sizeof(struct pedia),1,f);
}
}
我的问题就在这里
if(field.flag==0)
if中的语句从不为真我的猜测是,当我初始化文件内容或阅读它时,我做错了什么。有什么帮助吗?
void fileupdate(FILE *f,int filesize)
{
struct pedia field;
int k,key;
char opt[3];
while(1)
{
puts("nUPDATEn");
puts("nType the # of the registration you want to updatennkey:");
scanf("%d",&key);
getchar();
if(key>0 && key<=filesize)
{
fseek(f,sizeof(struct pedia)*key,0);
fread(&field.code,sizeof(int),1,f);
fread(&field.descr,sizeof(char)*50,1,f);
fread(&field.TM,sizeof(int),1,f);
fread(&field.pos,sizeof(int),1,f);
fread(&field.flag,sizeof(int),1,f);
if(field.flag==0)
{
.....
}
}
else
puts("nplease type a key between 0 and the number of the file registrationsnn");
}
}
您的代码中有几个问题:
-
无法逐个读取结构字段,因为在结构字段之间可能添加了填充(通常是这样)。这意味着,如果你的结构中有两个字段——
char
(比如1字节大)一个int,比如4 byte large
,那么你的结构很可能有8字节大,char和int之间有3个"空"字节。添加填充是因为对齐问题,这超出了本文的范围。为了解决这个问题,您应该一次读取整个结构,就像一次写入一样。然而,请注意,由于填充在不同的体系结构/C实现中可能不同,在这种情况下,您将无法在不同的机器之间自由移动文件,也无法期望程序正常工作。另一种更可移植的选择是逐字段写入结构。但同时,您还必须考虑如果您尝试用两台机器交换文件会发生什么,一台机器的int为4字节,另一台机器为8字节(这很不寻常,但可能)。是的,C实际上很难把它做好。 -
您的
key
值验证错误。应该允许key
等于0,因为这是存储第一条记录的地方。不过,它永远不应该大于(filesize/sizeof(struct pedia))-1
。 -
lseek
的最后一个参数应该是SEEK_SET
、SEEK_END
或SEEK_CUR
之一,而不是0
,因为您不能保证其他C实现将使用相同的数字来表示SEEK_SET
。事实是,在C实现的情况下,我们真的不知道0的含义,因为您没有检查调用的返回值,我们甚至不知道0
是否是有效值。
更不用说缺乏错误处理。。当你的代码行为不端时,这个就派上了用场。
您的读写不同步,可能是因为结构中存在填充,而在读取单个结构元素时没有考虑到填充。读取各个结构元素,仅按实际数据的大小而不是按数据+填充的大小来推进文件位置。在一次读取操作中从文件中读取整个结构,这只是写入数据的补充。