繁体   English   中英

可能无法从c中的二进制文件写入或读取

[英]prob either from writing or reading to/from binary file in c

如果您需要进一步的信息,请告诉我,以便我可以更新该信息。

我保存到文件的是以下结构的字段。 因为文件在开始时没有注册,所以我必须通过将标志设置为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("\nUPDATE\n");

        puts("\nType the # of the registration you want to update\n\nkey:");
        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 registrations\n\n");


    }

}

您的代码中有几个问题:

  1. 您不能一一读取结构域,因为在结构域之间可能(通常有)填充。 这意味着,如果您的结构中有两个字段char (例如1字节大)一个int,例如4 byte large ,则很可能您的结构将是8字节大,在char和an之间有3个“空”字节INT。 由于对齐问题超出了本文的范围,因此添加了填充。 为了解决此问题,您应该一次读取整个结构,就像您一次编写一样。 但是请注意,由于填充在不同的体系结构/ C实现上可能会有所不同,因此在这种情况下,您将无法在计算机之间自由移动文件并期望程序正常运行。 另一种更便于移植的选项是逐字段写入struct字段。 而且,然后,您还必须考虑如果尝试用两台机器交换文件,一台机器具有4字节int,一台机器具有8字节,这会发生什么(很不寻常,但可能)。 是的,C实际上很难做到正确。

  2. 您的key验证错误。 key应该允许等于0,因为这是第一条记录的存储位置。 但是,它永远不能大于(filesize/sizeof(struct pedia))-1

  3. 最后论证lseek应该是一个SEEK_SETSEEK_END ,或SEEK_CUR ,不是0 ,你有没有保证,其他C实现将使用相同的数字来表示SEEK_SET 事实是,对于C实现,我们真的不知道0的含义,因为您不检查调用的返回值,所以我们甚至不知道0是否为有效值。

更不用说缺少错误处理了..当您的代码行为不当时,它实际上会派上用场。

您的读取和写入不同步,可能是因为结构中存在填充,而您在读取单个结构元素时并未考虑填充。 读取各个结构元素,仅根据实际数据的大小而不是数据+填充的大小来推进文件位置。 通过一次读取操作从文件中读取整个结构,这只是对写入数据所做的补充。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM