#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    2
    Rep Power
    0

    Help with fwrite structure please?


    Hello. I'm trying to teach myself C from C for dummies. One of the exercises have you creating a "stock" program where you fwrite a structure. The problem I have it that it keeps writing only the first object in the structure and not the following two values. Someone telling me where I'm messing up would be greatly appreciated.

    struct stock_data {
    char name[30];
    float buy_price;
    float current_price;
    };

    void write_info(void)
    {
    FILE *stocks;
    struct stock_data stock;

    printf("Enter stock name:");
    gets(stock.name);
    printf("What did you buy it for? $");
    scanf("%f", &stock.buy_price);

    stock.current_price = stock.buy_price/11;

    stocks = fopen("stock.dat", "a");
    if(stocks==NULL)
    {
    puts("Error opening file");
    exit(1);
    }

    fwrite(&stock, sizeof(stock),1,stocks);
    printf("st = %d", st);
    fclose(stocks);
    puts("Stock added!");
    fflush(stdin);
    }


    This is only part of the program, but the part that I believe my mistake is in. Thanks in advance!
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    71
    Rep Power
    2
    How do you know that your only writing the first structure element?

    Also a note on coding in C, be very careful using the gets() function. I would try the fgets() function instead.
    Last edited by G4143; November 4th, 2012 at 10:31 AM.
  4. #3
  5. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,379
    Rep Power
    1871
    1. How do you know you didn't save everything?
    The resulting file is NOT a text file - you can't just load it into an editor and read the text. Well you'll see the .name field up to the first \0. After that, it's likely to be largely unprintable characters or seemingly gibberish.

    If the file is around 40 bytes long (print sizeof(stock) to find out how many), then the data is there.

    Another idea for windows users is to force binary mode ("ab","rb","wb" in the fopen call).

    Grab yourself a hex editor (eg HxD ) to see the content of arbitrary files.

    > fflush(stdin)
    Don't do this -> read this
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  6. #4
  7. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    2
    Rep Power
    0
    The reason I think only only the first item is recorded is because another function in the program is to read it, and it only shows the name of the stock. This is the function that does that.

    void read_info(void)
    {
    FILE *stocks;
    struct stock_data stock;
    int x;

    stocks=fopen("stock.dat", "r");
    if(stocks==NULL);
    {
    puts("No data in file");
    return;
    }

    while(TRUE)
    {
    x = fread(&stock, sizeof(stock), 1, stocks);
    if(x==0) break;
    printf("\nStock name: %s\n", stock.name);
    printf("Purchased for $%.2f\n", stock.buy_price);
    printf("Current price: $%.2f\n", stock.current_price);
    }

    fclose(stocks);
    }


    The other reason I think only the name is recorded is because i tried to view the stock.dat file using the following code.

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

    #define BUFSIZE 255

    void main(int argc, char *argv[])
    {
    FILE *viewfile;
    char buffer[BUFSIZE+1]; /* storage */

    /* check for proper no. of arguments */
    if(argc<2)
    {
    puts("Missing filename!");
    puts("\nHere is the format");
    puts("VIEW filename");
    exit(1);
    }

    /* Does the file exist? */

    viewfile = fopen(argv[1], "r");
    if(!viewfile)
    {
    printf("Error opening \"%s\"\n", argv[1]);
    exit(1);
    }

    /* display the file's guts */

    while(fgets(buffer,BUFSIZE,viewfile))
    printf("%s",buffer);
    fclose(viewfile);
    }

    When i use that program, the only thing that shows up is the name of the stock, no weird characters or anything afterwards.


    I did check sizeof(stock) and it did return a 40 value. But I know that the information is recorded into the structure before the file because I had that information printed to the screen to make sure. I guess I might be missing something else?

    Thanks for the help!?!?!
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    71
    Rep Power
    2
    You realize that this

    Code:
    while(fgets(buffer,BUFSIZE,viewfile))
    printf("%s",buffer);
    fclose(viewfile);
    Assumes your displaying c-strings and not raw binary data. Try something like below but with the proper error checking on things like fopen.

    Code:
    #include <stdio.h>
    #include <string.h>
    
    struct stock_data
    {
    	char name[30];
    	float buy_price;
    	float current_price;
    };
    
    int main(int argc, char**argv)
    {
    	FILE * fd = NULL;
    	struct stock_data my_stk, ans;
    	
    	strcpy(my_stk.name, "G4143");
    	my_stk.buy_price = 13.98;
    	my_stk.current_price = 34.98;
    	
    	fd = fopen("testfile", "w");
    	
    	fwrite(&my_stk, sizeof(struct stock_data), 1, fd);
    	
    	fclose(fd);
    	
    	fd = fopen("testfile", "r");
    	
    	fread(&ans, sizeof(struct stock_data), 1, fd);
    	
    	fclose(fd);
    	
    	fprintf(stdout, "name->%s, b_price->%f, c_price->%f\n", ans.name, ans.buy_price, ans.current_price);
    	
    	return 0;
    }
    Last edited by G4143; November 4th, 2012 at 04:29 PM.

IMN logo majestic logo threadwatch logo seochat tools logo