How can I write a stucture record into a text file using fwrite..

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Manoj Manu
    New Member
    • Sep 2015
    • 6

    How can I write a stucture record into a text file using fwrite..

    Iam trying to write student details in text file, But, i found that the file was filled with some gaurbage values.
    plz anyone can help me to find the solution.

    here is my code...
    Code:
    #include<stdio.h>
    #include<conio.h>
    struct student
    {
    	char roll_no[10];
    	char name[10];
    	char previous_payment[5];
    	char present_payment[5];
    	char total_payment[5];
    };
    int toint(char str[])
    {
        int len = strlen(str);
        int i, num = 0;
     
        for (i = 0; i < len; i++)
        {
            num = num + ((str[len - (i + 1)] - '0') * pow(10, i));
        }
     
       return num;
    }
    void tostring(char str[], int num)
    {
        int i, rem, len = 0, n;
     
        n = num;
        while (n != 0)
        {
            len++;
            n = n / 10;
        }
        for (i = 0; i < len; i++)
        {
            rem = num % 10;
            num = num / 10;
            str[len - (i + 1)] = rem + '0';
        }
        str[len] = '\0';
    }
    void main()
    {
    	int previous,present,total,choice;
    	char ch,str1[10],str2[10];
    	struct student std_data;
    	FILE *data,*report;
    	printf("Enter the following details of student\n");
    	printf("enter roll.no of the student:");
    	scanf("%s",&std_data.roll_no);
    	printf("enter student name:");
    	scanf("%s",std_data.name);
    	printf("enter the following bill payments of Roll.no : %s \n",std_data.roll_no);
    	printf("Enter previous payment:");
    	scanf("%d",&previous);
    	tostring(str1,previous);
    	printf("str1 = %s\n",str1);
    	printf("Enter present payment:");
    	scanf("%d",&present);
    	tostring(str2,present);
    	printf("str2 = %s\n",str2);
    	strcpy(std_data.previous_payment,str1);
    	printf("std_data.previous_payment = %s\n",std_data.previous_payment);
        strcpy(std_data.present_payment,str2);
    	printf("std_data.present_payment = %s\n",std_data.present_payment);
    	total = previous + present;
    	printf("total = %d\n",total);
    	tostring(std_data.total_payment,total);
    	printf("std_data.total_payment = %s\n",std_data.total_payment);
    	printf("\n");
    	data = fopen("student_details.txt","a");
    	if(data == NULL)
    	{
    		printf("error in opening input_details file\n");
    		exit(1);
    	}
    	fwrite(&std_data,sizeof(struct student),1,data);
    	fclose(data);
    	return;
    }
    Last edited by Stewart Ross; Sep 21 '15, 10:46 AM. Reason: Added code tags to the code section
  • weaknessforcats
    Recognized Expert Expert
    • Mar 2007
    • 9214

    #2
    You are writing the entire struct to the file so if your name member is John I would expect you would see John followed by six garbage values. That's because the data is 4 characters leaving six unfilled values for the rest of the 10 char array.

    When writing files it's good to do so in a manner such that someone else can read them. You might consider filling the unused elements in your arrays with spaces so that a 10 element array writes 10 bytes. I would avoid writing \0 terminators to disc.

    Then when you need to read the file you can read 10 bytes into the name member which is 10 bytes.

    Also, do not use strcpy. It does not pay attention to your array sizes. It copies until it finds a \0. If it copies more than 9 bytes it corrupts your stack memory. Use strncpy or something like it. That way for a 10 element array you can tell strncpy to copy 10 bytes.

    Comment

    • Clearner321
      New Member
      • Sep 2015
      • 22

      #3
      Just one doubt I have, you said to avoid writing \0, but in the case of scanf the function by default adds \0. So, how to handle this case.

      Comment

      • weaknessforcats
        Recognized Expert Expert
        • Mar 2007
        • 9214

        #4
        If you have a 10 char array and strcpy puts a string in there you can strlen that string to get the length of the string without the \0.

        So JOHN\0 would be 4 according to strlen. That would be elements 0,1,2,3. Just move spaces into elements 4,5,6,7,8,9 and you have only data in the array.

        This \0 stuff is a C convention from 1968. Various C functions are written to expect a \0. It's OK to use this internally in a program but when data goes outside the program these C conventions should not go out with the data.

        If you try to the add the data in Oracle, those \0 will cause trouble. Ditto in Access and MySQL.

        There s a law that says you can't read a file unless you know how it was written. I use the Method of Least Astonishment by not having weird format bytes embedded in the data.

        Here's what I would do:

        Create a buffer array large enough for any of your strings. Use this buffer with scanf.
        Then write a Load function where you pass in your array address, the length of the array, and the address of the buffer. Internally, the load function will load the array with the number of bytes in the argument. It will start with position 0 and copy bytes from the buffer to the array one by one until it gets to the \0 in the buffer. Now it does not copy the \0 to the array but instead starts copying spaces in to the array until the array is full.

        From here on you read/write the entire array.

        Comment

        • Clearner321
          New Member
          • Sep 2015
          • 22

          #5
          Great I was not aware of the background of \0 and the way to use it. Thank you.

          Comment

          • Manoj Manu
            New Member
            • Sep 2015
            • 6

            #6
            Thank u sir for your valuable suggestion.
            I have one doubt sir, when i used fprintf for writing into the file i didn't get any problem and also i didn't find any gaurbage values.
            But, in case of fwrite only why iam getting this problem.
            Can you please explain what's the difference between these two function calls.

            Comment

            • Clearner321
              New Member
              • Sep 2015
              • 22

              #7
              Code:
              int fprintf ( FILE * stream, const char * format, ... );
              is used for printing strings. It will try to print till a null character is found. In case of
              Code:
              size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
              Writes an array of count elements, each one with a size of size bytes, from the block of memory pointed by ptr to the current position in the stream and does not look for null character, Ex: If the array size is 10 it will write all the 10 bytes into the file, so we should try to fill the non data with spaces as was explained previously. Please correct me if I am wrong.

              Comment

              Working...