Question

if you need any info further from what i ve posted below please let me know so i can update the post.

What i save to the file is the fields of the struct below. Because the file has no registrations in the beginning i have to initialize it by setting the flag to 0.

struct pedia
{
    int code;
    char descr[50];
    int TM;
    int pos;
    int flag;
};

I open a file at/from which i can both write/read using

if((fp=fopen(name,"wb+"))==NULL)

user gives the maximum number of registrations that can be saved in the file

later i send the pointer fp in a function to initialize the file like this

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);

    }

}

my problem is right here

if(field.flag==0)

the statement in the if is never true My guess is that i do something wrong when i initialize the file content or when i m reading it.Any help?

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");


    }

}
Was it helpful?

Solution

There are couple of problems in your code:

  1. You can't read struct fields one by one because there may be (an usually there is) padding added between struct fields. This means that if you have two fields in your struct - char (say, 1 byte large) an int, say 4 byte large, it's very likely that your struct will be 8 bytes large with 3 "empty" bytes between the char and an int. The padding is added because of alignment issues which are out of scope of this post. In order to fix this, you should read whole struct at once, just like you write it at once. Note, however, that since padding may be different on different architectures/C implementations, in this case you won't be able to freely move your files from machine to machine and expect your program to work. The other option, more portable, is to write the struct field by field. But also then, you have to consider what happens if you try exchanging you file with two machines, one with 4 byte int and one with 8 byte (quite unusual but possible). Yeah, C is actually hard to get it right.

  2. Your key value validation is wrong. key should be allowed to be equal 0 since this is where first record will be stored. It should never be larger than (filesize/sizeof(struct pedia))-1, though.

  3. Last argument of lseek should be one of SEEK_SET, SEEK_END, or SEEK_CUR, not 0 as you have no guarantee that other C implementation will use the same number to represent SEEK_SET. The truth is, we can't really know what 0 means in case of your C implementation an since you don't check return value of the call, we can't even know if 0 is valid value there.

Not to mention lack of error handling.. and that one actually comes in handy when your code is misbehaving.

OTHER TIPS

Your reading and writing are out of sync, probably because there is padding in the structure, which is not being accounted for when you read individual structure elements. The individual structure elements are read, advancing the file position only by the size of the actual data, rather than by the size of the data+padding. Read the entire structure from the file in one read operation, just the complement of what you do to write the data.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top