Search code examples
cfilec99

how fwrite() works in c files?


fwrite() is used to write structure to the file in c, suppose we have following structure:

struct student{
int rollno;
char name[20],grade;
float total;
};
  • does it write full sizeof(struct tudent)bytes to the file every time we write it with fwrite()?
  • if so then does it write name with 20 bytes of storage on the file even if you have only stored few characters in the name?
  • if that is the case then can we modify the the written record using fread() with other functions such as fputs() fputc() putw(), but these function doesnt seem to modify the record correctly?

    #include<stdio.h>
    #include<stdlib.h>
    struct student{
        int rollno;
        char name[20],grade;
        float total;
    };
    void display(struct student s2  ){
        printf("Name: %s\nRoll Number: %d\nTotal markes: %f\nGrade: %c",s2.name,s2.rollno,s2.total,s2.grade);
    }
    int main(){
        struct student s1,s2;
        FILE *fp;
        int choice;
        fp=fopen("file.txt","r+");
        if(!fp){
            printf("\nerror in opening file.txt");
            exit(1);
        }
        printf("Enter student detail:-\nEnter name: ");
        scanf("%s",s1.name);
        printf("Enter rollno: ");
        scanf("%d",&s1.rollno);
        printf("Enter the total marks: ");
        scanf("%f",&s1.total);
        printf("Enter the grade: ");
        scanf(" %c",&s1.grade);
        fwrite(&s1,sizeof(s1),1,fp);
        fseek(fp,0,SEEK_SET);
        fread(&s2,sizeof(s2),1,fp);
        display(s2);
        printf("\nModify student record");
        while(1){
            printf("\n1: modify name\n2: modify rollno\n3: Exit\nchoice: ");
            scanf("%d",&choice);
            switch(choice){
                case 1: printf("\nEnter  name: ");
                        scanf("%s",s1.name);
                        fseek(fp,0,SEEK_SET);
                        fputs(s1.name,fp);
                        fseek(fp,0,SEEK_SET);
                        fread(&s2,sizeof(s2),1,fp);
                        display(s2);
                        break;
                case 2: printf("\nEnter rollno");
                        scanf("%d",&s1.rollno);
                        fseek(fp,sizeof(s1.name),SEEK_SET);
                        putw(s1.rollno,fp);
                        fseek(fp,0,SEEK_SET);
                        fread(&s2,sizeof(s2),1,fp);
                        display(s2);
                default:fclose(fp);
                        return 0;
            }
        }
        return 0;
    }
    

Solution

  • fwrite is a C function and deals with structures the way other functions do, without doing any special treatment (unless requested). It takes that struct as a binary object, and writes as many bytes as you want of it.

    does it write full sizeof(struct tudent)bytes to the file every time we write it with fwrite()?

    It writes the size you ask fwrite to write, so if it's sizeof(structX) it writes that size. If you do the same fwrite twice, it will be written twice.

    if so then does it write name with 20 bytes of storage on the file even if you have only stored few characters in the name?

    name is declared as char[20] which takes 20 bytes. So yes that part takes 20 bytes on disk (even if the "string" contains "only" 3 characters (i.e. a '\0' is at the 4th position), all 20 bytes are written).

    if that is the case then can we modify the the written record using fread() with other functions such as fputs() fputc() putw(), but these function doesnt seem to modify the record correctly?

    putw writes a word to the stream, meaning an int as it is (a binary word, not its string representation), but better use fwrite as recommended in the man page. fputc writes a unique character. fputs writes a null-terminated string, unlike fwrite which writes the number of characters you require regardless if a zero-byte is hidden somewhere in it.