-1

Hi I am trying to write a structure to a file. Below is the code.

   #include<stdio.h>
   #include<string.h>
   #include<stdlib.h>

    /*structure*/ 
    struct student
    {
        char name[10];
        char space[1];
        char rollno[5];
    }head_rec;

    /*main*/
    void main()
    {
        FILE *fout;
        if(fout=fopen("output.txt","w")==NULL)
        {
            printf("Cannot open the file to write");
            exit;
        }
        memset(&head_rec,'\0',sizeof(struct student);
        sprint(head_rec.name,"SOUMYA",6);
        memset(head_rec.space,' ',1);
        memset(head_rec.rollno,'\0',sizeof(head_rec.rollno);
        sprint(head_rec.rollno,"0000",4);
        head_rec.rollno[4]='\0';
        fwrite(&head_rec,sizeof(struct student),1,fout);
    }

Output:

SOUMYA 0000^@

How to get rid of that last character?

n0p
  • 3,399
  • 2
  • 29
  • 50
  • also, its better to use `fprintf()` over `fwrite()` for human readable outputs. – Sourav Ghosh Dec 10 '14 at 07:19
  • I wanted to write the whole structure, not the individual members. Is it possible with fprintf? – Soumya Saraswata Dash Dec 10 '14 at 07:22
  • before that, please let us know, what is this `if(fout=fopen("output.txt","w"))`? do you know what you're doing? – Sourav Ghosh Dec 10 '14 at 07:23
  • 4
    you're code won't compile. Please show us the actual code. – Sourav Ghosh Dec 10 '14 at 07:24
  • collection of individual member variables == the structure. and moreover `fwrite()` is for `binary stream input/output`, not suitable for `formatted output` – Natasha Dutta Dec 10 '14 at 07:28
  • Alignment. Structures are aligned so its size may be different from sum of its elements sizes. Compilers depending on optimization flags and target architechture may insert paddings between structure fields – user3159253 Dec 10 '14 at 07:37
  • you also need to take care of padding in the `struct`, i.e. the sizes of the elements in the `struct` will be expanded to match the word length! – H_squared Dec 10 '14 at 07:37
  • 1
    @Sourav Doesn't fopen have a return value? That value would be used in evaluating the "if" – Marichyasana Dec 10 '14 at 07:37
  • @Marichyasana yes, it has a return value and i think somehow I know that. is that _all_ you spotted by follwing my comment? – Sourav Ghosh Dec 10 '14 at 07:39
  • @Marichyasana It has a return value, but the OP should be testing its inverse i.e. do `if (!(fout = fopen(...)))`. In the current state, if the file is opened successfully it'll print an error message and exit. – legends2k Dec 10 '14 at 07:53
  • @2501 sir, OPoA deleted the answer, but as per your comment there, can you please explain [this](http://codepad.org/1UMkmLxX) code and o/p? I'll be thankful. – Sourav Ghosh Dec 10 '14 at 07:55
  • @Sourav Sorry missed the NULL check. I meant if(fout=fopen("output.txt","w")==NULL) – Soumya Saraswata Dash Dec 10 '14 at 08:31
  • @user3159253 Do you have any solution to avoid padding? – Soumya Saraswata Dash Dec 10 '14 at 08:42
  • Sometimes, there're solutions, sometimes there aren't, it's just unavoidable like, don't know, like gravitation. Add a manual padding bytes (usually each field is aligned to 4 or 8 bytes), combine several small fields into a big one of "good size" using bitfields and so on. Also look at @hhachem recipe, it's not a silver bullet, but may help in certain situations – user3159253 Dec 10 '14 at 09:04

1 Answers1

1

Since you are writing the whole struct to the file, you need to avoid padding. This can be done this way:

#pragma pack(push)
#pragma pack(1)
     struct student
        {
         char name[10];
         char space[1];
         char rollno[5];
        }head_rec;
#pragma pack(pop)

Also your main function must return an integer value. So change void main() to int main()

On a different note: use snprintf instead of sprintf, so you can specify the maximum size of the destination buffer, which makes it safer.

Plus:

if(fout=fopen("output.txt","w"))

should be :

 if((fout=fopen("output.txt","w"))==NULL)
H_squared
  • 1,251
  • 2
  • 15
  • 32
  • Thanks for your help. But it is not working for me. :( – Soumya Saraswata Dash Dec 10 '14 at 08:51
  • @SoumyaSaraswataDash well if you want to write a `struct` with `char arrays`, you need to avoid the null character at the end of the character array! Otherwise it will be written to the file. You also need to make sure each array is as big as the number of characters you want to store. So storing "SOUMAYA" in name which is 10 bytes long will not work as the bytes following the terminating null character are undefined. So "SOUMAYA" will have to be store in an array of exactly 7 bytes. However, I suggest using something like: (to be continued)... – H_squared Dec 10 '14 at 09:45
  • `snprintf(temp,sizeof(temp),"%s%s%s",head_rec.name,head_rec.space,head_rec.rollno);fwrite(temp,1,strlen(temp),fout);` and don't forget to `fclose(fout);fout=NULL;` – H_squared Dec 10 '14 at 09:47