Thread: Struct size incorrect

  1. #16
    Registered User
    Join Date
    Oct 2007
    Posts
    38
    Im still unable to make this program work...

    Ok, here's what I did:

    In the menu I gave the user a choice to add new product, modify the name of a specific product or exit. In the structure i removed all numeral values and left just 3 chars set to 5 bytes each so that it would be easier to read it from the file...

    I added 3 new items to the "database":
    Value1: Value2: Value3:
    11111 aaaaa zzzzz
    22222 bbbbb yyyyy
    33333 cccccc xxxxx

    So, what i get written into the file are 3 separate entries, all follow each other:
    Code:
    11111aaaaazzzzz22222bbbbbyyyyy33333cccccxxxxx
    Now i run the program and go to part b (to modify the name - 11111, 22222 or 33333)...
    The program asks me what product i want to change (1-3). I say 2. Write the new description: 55555 and get the following in the updated file:

    Code:
    11111aaaaazzzzz55555 A      33333cccccxxxxx
    The above happens when I exit the program and reenter to edit the name... If I dont exit, and modify the description as soon as i add the 3 products i get the following:
    Code:
    11111aaaaazzzzz55555 ccccxxxxx33333cccccxxxxx

    How do I go about making this work?


    P.S.

    Here's the code:

    Code:
    #include <stdio.h>
    
    struct product {
    	char name[5];
    	char price[5];
    	char quantity[5];
    };
    
    int main() {
    
    	int menu_stock(char*);
    	char choice_stock;
    	void add_product(product*);
    	void change_description(product*);	
    	void seek_product_number(int, FILE*);
    	int total_products(FILE*);
    	int get_product_number(int);
    	void seek_end_db(FILE*);
    	void write_to_db(FILE*, product*);
    
    	product p;
    	FILE *file_sales;
    
    	file_sales = fopen("./sales.txt", "r+");
    
    	while(menu_stock(&choice_stock) == 1) {
    		switch(choice_stock) {
    			case 'A':
    			case 'a':
    				add_product(&p);
    				seek_end_db(file_sales);
    				write_to_db(file_sales, &p);
    				break;
    			case 'B':
    			case 'b':
    				seek_product_number(get_product_number(total_products(file_sales)), file_sales);
    				change_description(&p);
    				write_to_db(file_sales, &p);
    				break;
    		}
    	}
    }
    
    int menu_stock(char *c) {
    	void clear_input_buffer();
    	do {
    		printf("*****************************************\n");
    		printf("* Add new product                   (A) *\n");
    		printf("* Change product description        (B) *\n");
    		printf("* Exit                              (X) *\n");
    		printf("*****************************************\n");
    		printf("                               --> ");
    		*c = (char)getchar();
    		clear_input_buffer();
    	} while(*c != 'A' && *c != 'a' && *c != 'B' && *c != 'b' && *c != 'X' && *c != 'x');
    	if(*c == 'X' || *c == 'x') return 0;
    	else return 1;
    }
    
    void clear_input_buffer() {
    	int ch;
    	while ((ch = getchar()) != '\n' && ch != EOF);
    	clearerr(stdin);
    }
    
    void add_product(product *p) {
    	printf("Enter product description : ");
    	gets(p->name);
    	printf("Enter price per unit (cent) : ");
    	gets(p->price);
    	printf("Enter stock level: ");
    	gets(p->quantity);
    }
    void change_description(product *p) {
    	printf("Enter product description : ");
    	gets(p->name);
    }
    void seek_end_db(FILE *file_sales) {
    	fseek(file_sales, 0, SEEK_END);
    }
    void write_to_db(FILE *file_sales, product *p) {
    	fwrite(p, sizeof(product), 1, file_sales);
    }
    
    
    void seek_product_number(int product_number, FILE *file_sales) {
    	fseek(file_sales, (product_number - 1) * sizeof(product), SEEK_SET);
    }
    int total_products(FILE *file_sales) {
    	int file_size;
    	fseek(file_sales, 0, SEEK_END);
    	file_size = ftell(file_sales);
    	return file_size / sizeof(product);
    }
    int get_product_number(int totalproducts) {
    	int product_number;
    	void clear_input_buffer();
    	if(totalproducts <= 1) {
    		return 1;
    	}
    	else {
    		do {
    			printf("Enter product number (1 - &#37;d): ", totalproducts);
    			scanf("%d", &product_number);
    			clear_input_buffer();
    		} while(product_number <= 0 || product_number > totalproducts);
    		return product_number;
    	}
    }
    Last edited by Karpaty; 11-26-2007 at 11:46 AM.

  2. #17
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    The first thing I see is that your declarations are put inside your functions - this is wrong. They're supposed to be in your header or at the start of your file.
    I'll fire up the debugger and take a look at it for you.
    Just one question: is this windows or linux, or some such? Windows use "\" while linux use "/".
    The second thing is, using a struct name directly without "struct" first is illegal in C. Use something li,e:
    Code:
    typedef struct product product;
    I'm not surprised you get that bug. That's beacuse you put 55555 into name, but the rest of the struct is not initialized. Further, you write the ENTIRE struct to the file.
    There are two options: read previous data for the product into the struct or seek to the offset of the product + name and then write only name.
    Last edited by Elysia; 11-26-2007 at 11:51 AM.

  3. #18
    Registered User
    Join Date
    Oct 2007
    Posts
    38
    Its Windows... thank you

  4. #19
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Yay, the good old "I want to read a chunk of formatted binary data directly into a struct" discussion. Yes, you can pack the struct using compiler settings. No, you shouldn't do that. You should never, ever care what the precise value of a sizeof() is.

  5. #20
    Registered User
    Join Date
    Oct 2007
    Posts
    38
    Quote Originally Posted by brewbuck View Post
    Yay, the good old "I want to read a chunk of formatted binary data directly into a struct" discussion. Yes, you can pack the struct using compiler settings. No, you shouldn't do that. You should never, ever care what the precise value of a sizeof() is.
    If this has been discussed before, can you please point me to where I can read about it... I searched this forum for hours and couldnt find much help. perhaps i was searching for the wrong keywords?

  6. #21
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    A few finds:
    http://cboard.cprogramming.com/showt...ry+file+create
    http://cboard.cprogramming.com/showt...ry+file+create

    It is a commonly discussed subject - creating binary files is not a good idea for portability between compilers, architectures or OS's - and one or two of those may be useful to consider - what if you need to migrate to Windows 64-bit because your major customer(s) are doing that? What if your major customer is moving to Linux? What if you find that the current compiler can't do what you need, and you want to upgrade to the next version, which just so happens to not have the same rules on data-layout in structs?

    [It is fine to break the rules if you know them - and the consequences of doing so ]

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #22
    Registered User
    Join Date
    Oct 2007
    Posts
    38
    I finally got it working... It was quite simple actually...
    The way I got it to work is, as suggest by Elysia, by reading the previous data for the product into the structure and only then changing the name... Also, one pitfall that I got on my way: I had a char array of [5] and was adding a new name 5 characters long. It messed up my price part, since my string array could only store 4 chars due to the fact that the last (5th) byte was reserved for "\0" character...

    Big 'THANK YOU' to everyone who helped me...
    Last edited by Karpaty; 11-28-2007 at 07:28 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. char Handling, probably typical newbie stuff
    By Neolyth in forum C Programming
    Replies: 16
    Last Post: 06-21-2009, 04:05 AM
  2. Assignment HELP!!
    By cprogrammer22 in forum C Programming
    Replies: 35
    Last Post: 01-24-2009, 02:24 PM
  3. Adventures in labyrinth generation.
    By guesst in forum Game Programming
    Replies: 8
    Last Post: 10-12-2008, 01:30 PM
  4. Replies: 10
    Last Post: 05-18-2006, 11:23 PM
  5. Replies: 11
    Last Post: 03-25-2003, 05:13 PM