Thread: Improper Scanning of Redirected Input

  1. #1
    Registered User
    Join Date
    Oct 2005
    Posts
    19

    Improper Scanning of Redirected Input

    The following code reads a file containing (on each line): Code, Price, Amount. Then it calculates taxes, shipping costs, etc. and consequently, the grand total of each purchase (or each line). At one point, the output calculations seem to be incorrect, and the program ran in an infinite loop. I somehow fixed this (please tell me why this could happen in the first place so know my mistake). Now, instead of reading a line containing (code, price, amount) and storing code in 'x', price in 'y', and amount in 'z', it processed each part of the line (code, price, amount) in x and leaves y and z empty. In addition, the numbers seem to be absolutely huge. I don't know why. Do i have to set some variable(s) to zero in the beginning of the while loop?

    Here is the input, code, and output.

    Input.
    12345570 32 2
    12335770 37 1
    Code.
    Code:
    #include <stdio.h>
    
    int main()
    {
    
    	int prod_num, number, counter=0, major_code, minor_code, tax_code, manuf_code;
    	double base_cost, minor_factor, shipping_costs, tax_amount, final_unitprice, grand_total;
    
    	while ( scanf("%d, %lf, %d", &prod_num, &base_cost, &number) !=EOF)
    	{
    
    		counter++;
    		major_code = prod_num / 100000;
    		minor_code = (prod_num % 100000) / 100;
    		tax_code = (prod_num % 100) / 10;
    		manuf_code = prod_num % 10;
    		
    		if(minor_code >= 0 && minor_code <= 339) {
    			minor_factor = 1.45;
    		}
    
    		else if ((minor_code>=400 && minor_code <=799) || (minor_code>=950 && minor_code <=955)) {
    			minor_factor = 1.12;
    		}	
    		
    		else {
    			minor_factor = 0.89;
    		}
    
    		switch(manuf_code)
    		{
    			case 0:		shipping_costs = 7.50;
    						break;
    
    			case 1:		shipping_costs = 8.47;
    						break;
    
    			case 2:		shipping_costs = 6.05;
    						break;
    
    			case 3:		shipping_costs = 10.20;
    						break;
    
    			default:	shipping_costs = 20.00;
    						break;
    		
    		}
    
    		if(tax_code == 1) 
    
    			{
    
    			if(major_code>=0 && major_code<=250)
    				tax_amount = 0.12;
    			
    			else if(major_code>=251 && major_code<=450)
    				tax_amount = 0.15;
    
    			else
    				tax_amount = 0.25;
    
    			}
    
    		else if (tax_code == 0)
    			tax_amount = 0;
    
    		final_unitprice = base_cost * minor_factor;
    		grand_total = final_unitprice * number * (1 + tax_amount);
    		
    		printf("----------------------> PRODUCT [%d] <----------------------\n", counter);
    		printf("\n");
    		printf("Product #: %d || Final Unit Price: %.2f || Number of products ordered: %d || Total Billed: %f || \n", prod_num, final_unitprice, number, grand_total);
    		printf("\n");
    
    	}
    
    	return 0;
    }
    Output.
    ----------------------> PRODUCT [1] <----------------------

    Product #: 12345570 || Final Unit Price: 125847577913758180000000000000000000000
    00000000000000000000000000000000000000000000000000 000000000000000000000000000000
    00000000000000000000000000000000000000000000000000 000000000000000000000000000000
    00000000000000000000000000000000000000000000000000 00.00 || Number of products or
    dered: 4 || Total Billed: 1.#INF00 ||

    ----------------------> PRODUCT [2] <----------------------

    Product #: 32 || Final Unit Price: 162927667834776190000000000000000000000000000
    00000000000000000000000000000000000000000000000000 000000000000000000000000000000
    00000000000000000000000000000000000000000000000000 000000000000000000000000000000
    0000000000000000000000000000000000000000000000.00 || Number of products ordered:
    4 || Total Billed: 1.#INF00 ||

    ----------------------> PRODUCT [3] <----------------------

    Product #: 2 || Final Unit Price: 1629276678347761900000000000000000000000000000
    00000000000000000000000000000000000000000000000000 000000000000000000000000000000
    00000000000000000000000000000000000000000000000000 000000000000000000000000000000
    000000000000000000000000000000000000000000000.00 || Number of products ordered:
    4 || Total Billed: 65171067133910475000000000000000000000000000000000 00000000000
    00000000000000000000000000000000000000000000000000 000000000000000000000000000000
    00000000000000000000000000000000000000000000000000 000000000000000000000000000000
    000000000000000000000000000000.000000 ||

    ----------------------> PRODUCT [4] <----------------------

    Product #: 12335770 || Final Unit Price: 100003878877897120000000000000000000000
    00000000000000000000000000000000000000000000000000 000000000000000000000000000000
    00000000000000000000000000000000000000000000000000 000000000000000000000000000000
    00000000000000000000000000000000000000000000000000 00.00 || Number of products or
    dered: 4 || Total Billed: 40001551551158849000000000000000000000000000000000 0000
    00000000000000000000000000000000000000000000000000 000000000000000000000000000000
    00000000000000000000000000000000000000000000000000 000000000000000000000000000000
    0000000000000000000000000000000000000.000000 ||

    ----------------------> PRODUCT [5] <----------------------

    Product #: 37 || Final Unit Price: 162927667834776190000000000000000000000000000
    00000000000000000000000000000000000000000000000000 000000000000000000000000000000
    00000000000000000000000000000000000000000000000000 000000000000000000000000000000
    0000000000000000000000000000000000000000000000.00 || Number of products ordered:
    4 || Total Billed: 65171067133910475000000000000000000000000000000000 0000000000
    00000000000000000000000000000000000000000000000000 000000000000000000000000000000
    00000000000000000000000000000000000000000000000000 000000000000000000000000000000
    0000000000000000000000000000000.000000 ||

    ----------------------> PRODUCT [6] <----------------------

    Product #: 1 || Final Unit Price: 1629276678347761900000000000000000000000000000
    00000000000000000000000000000000000000000000000000 000000000000000000000000000000
    00000000000000000000000000000000000000000000000000 000000000000000000000000000000
    000000000000000000000000000000000000000000000.00 || Number of products ordered:
    4 || Total Billed: 65171067133910475000000000000000000000000000000000 00000000000
    00000000000000000000000000000000000000000000000000 000000000000000000000000000000
    00000000000000000000000000000000000000000000000000 000000000000000000000000000000
    000000000000000000000000000000.000000 ||


    Any key to return to Quincy...

  2. #2
    Registered User
    Join Date
    Feb 2003
    Posts
    596
    First of all you're not entering your input the way you formatted it in scanf.

    If your scanf format string is "%d, %lf, %d", you have to enter the data exactly that way: an integer followed by a comma followed by a double followed by another comma followed by an integer followed by <enter>.

    If you want to enter it as
    [integer] <enter>
    [double] <enter>
    [integer] <enter>
    as you seem to be doing, break up the scanf command into three separate commands, each one reading in a single value.

    Also, it would be nice to precede the scanf with a printf to prompt for the appropriate input.

    Another problem: for product number 12345570 your formula gives a tax_code of 7; your program only handles tax_code 0 or 1. The result is that you are using an undefined tax_amount in the multiplication that determines grand_total. That is giving the huge numbers.

  3. #3
    Registered Luser cwr's Avatar
    Join Date
    Jul 2005
    Location
    Sydney, Australia
    Posts
    869
    Originally:

    Actually, "%d %lf %d " will support [integer]<enter>[double]<enter>[integer]<enter>, because the <enter> is whitespace, and the space in the format string will match on any whitespace. It's the commas that will confuse it, since they require the user to enter a comma, then some whitespace, in the case of "%d, %lf, %d".

    Edit (corrected, see below, thanks):

    Actually, "%d %lf %d " will support [integer]<enter>[double]<enter>[integer]<enter>, because the <enter> is whitespace, and the space in the format string will match on any whitespace. It's the commas that will confuse it, since they require the user to enter a comma, then optionally some whitespace, in the case of "%d, %lf, %d".
    Last edited by cwr; 10-20-2005 at 08:56 PM.

  4. #4
    Registered User
    Join Date
    Feb 2003
    Posts
    596
    Actually, "%d, %lf, %d" will accept [integer],[double],[integer]<enter> with no whitespace (except the final <enter>) because one or more whitespace characters in a scanf format string match zero or more whitespace characters in the input stream.

  5. #5
    Registered User
    Join Date
    Oct 2005
    Posts
    19
    The code does seem to read the input text correctly now.
    However, the calculated total price is wrong. Actually, it's a completely random huge number. Any ideas?

    I was told that i must initialise all my variables in the beginning of the loop. What does this mean? Do i have to set them all to zero at the beginning of the loop?

  6. #6
    Registered User
    Join Date
    Oct 2005
    Posts
    19
    I seem to have fixed it:
    Code:
    #include <stdio.h>
    
    int main()
    {
    
    	int prod_num, number, counter=0, major_code=0, minor_code=0, tax_code=0, manuf_code=0;
    	double base_cost, minor_factor=0, shipping_costs=0, tax_amount=0, final_unitprice=0, grand_total=0;
    
    	while ( scanf("%d %lf %d", &prod_num, &base_cost, &number) !=EOF)
    	{
    		counter++;
    		major_code = prod_num / 100000;
    		minor_code = (prod_num % 100000) / 100;
    		tax_code = (prod_num % 100) / 10;
    		manuf_code = prod_num % 10;
    		
    		if(minor_code >= 0 && minor_code <= 339) {
    			minor_factor = 1.45;
    		}
    
    		else if ((minor_code>=400 && minor_code <=799) || (minor_code>=950 && minor_code <=955)) {
    			minor_factor = 1.12;
    		}	
    		
    		else {
    			minor_factor = 0.89;
    		}
    
    		switch(manuf_code)
    		{
    			case 0:		shipping_costs = 7.50;
    						break;
    
    			case 1:		shipping_costs = 8.47;
    						break;
    
    			case 2:		shipping_costs = 6.05;
    						break;
    
    			case 3:		shipping_costs = 10.20;
    						break;
    
    			default:	shipping_costs = 20.00;
    						break;
    		
    		}
    
    		if(tax_code == 1) 
    
    			{
    
    			if(major_code>=0 && major_code<=250)
    				tax_amount = 0.12;
    			
    			else if(major_code>=251 && major_code<=450)
    				tax_amount = 0.15;
    
    			else
    				tax_amount = 0.25;
    
    			}
    
    		else if (tax_code == 0)
    			tax_amount = 0;
    
    		final_unitprice = base_cost * minor_factor;
    		grand_total = final_unitprice * number * (1 + tax_amount);
    		
    		printf("----------------------> PRODUCT [%d] <----------------------\n", counter);
    		printf("\n");
    		printf("Product #: %.2d || Final Unit Price: %.2f || Number of products ordered: %d || Total Billed: %.2f || \n", prod_num, final_unitprice, number, grand_total);
    		printf("\n");
    
    	}
    
    	return 0;
    }
    Output:
    ----------------------> PRODUCT [1] <----------------------

    Product #: 43264321 || Final Unit Price: 44.80 || Number of products ordered: 2
    || Total Billed: 89.60 ||

    ----------------------> PRODUCT [2] <----------------------

    Product #: 18962329 || Final Unit Price: 76.16 || Number of products ordered: 12
    || Total Billed: 913.92 ||


    Any key to return to Quincy...

  7. #7
    Registered User
    Join Date
    Oct 2005
    Posts
    19
    Another question, what does "modular fashion" mean in regards to a written code?

  8. #8
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    It means, don't have any really big functions. Split your code into smaller functions with a more specific task.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Input statement problem
    By une in forum C Programming
    Replies: 3
    Last Post: 05-29-2007, 11:16 PM
  2. For loop problems, input please.
    By xIcyx in forum C Programming
    Replies: 2
    Last Post: 04-22-2007, 03:54 AM
  3. I would love some input on my BST tree.
    By StevenGarcia in forum C++ Programming
    Replies: 4
    Last Post: 01-15-2007, 01:22 AM
  4. Simple Console Input for Beginners
    By jlou in forum C++ Programming
    Replies: 0
    Last Post: 06-21-2005, 01:50 PM
  5. Stupid Question
    By digdug4life in forum C++ Programming
    Replies: 22
    Last Post: 05-17-2005, 11:43 AM