Thread: New to C, scanf help

  1. #1
    Registered User
    Join Date
    Feb 2006
    Posts
    6

    New to C, scanf help

    Just a heads up, this is for a class assignment, but I'm only asking for help with one part of it. Basically we need to make a cash register type program, with the ability to add an item, compute change, print a total, reset it, and also some extra functions for converting the total to binary and hex. The main restriction however is that scanf is only allowed to read using %c, so no reading things as numbers or a whole line. This is kinda where my problem comes in, as I'm not sure how C actually does this. Here's the code I'm using for my main menu:

    Code:
    void main()
    {
    	float sum = 0;
    	float change = 0;
    	char command = '0';
    	int runCommand = TRUE;
    
    	printMenu();
    
    	while (command!='6') 
    	{
    		scanf(" %c", &command);
    		if(command=='1') {
    			sum += enterItem();
    			printMenu();
    		}
    		else if(command=='2') {
    			printf("%s%.2f\n\n", "The total cost is: $", sum);
    			printMenu();
    		}
    		else if(command=='3') {
    			printf("%s%.2f\n\n", "The total cost is: $", sum);
    			printMenu();
    		}
    		else if(command=='4') {
    			change = computeChange(sum);
    			printf("%s%5.2f\n\n", "The total change is: $", change);
    			printMenu();
    		}
    		else if(command=='5') {
    			sum = 0;
    			printf("%s\n\n", "The cash register has been reset.");
    			printMenu();
    		}
    		else if(command=='6') {
    			break;
    		}
    		else {
    			printf("Incorrect option.\n");
    			printMenu();
    		}
    		
    	}
    	return;
    }
    So far it seems to be working fine when only one character is entered, but when the user enters multiple characters it reprints the menu multiple times and goes through doing the right command, or printing the error message, for each character. My question is this: how can I make it print an error message and the menu once if the user enters multiple characters as one input? I've got a bunch of other problems I need to figure out, but with this out of the way I think I can figure them out. Thanks for any help.

  2. #2
    Devil's Advocate SlyMaelstrom's Avatar
    Join Date
    May 2004
    Location
    Out of scope
    Posts
    4,079
    Code:
    #include <stdio.h>
    
    int main() {
       int num;
       char string[20];
    
       printf("Enter a number: ");
       scanf("%d",&num);
       printf("%d\n", num);
       printf("Enter a string: ");
       scanf("%s", string);
       printf("%s", string);
       
       return 0;
    }
    
    /* Output */
    /* Enter a number: 5
    5
    Enter a string: Hello
    Hello              
    */
    In the words of Scooby Doo. "Buuuuurrrrr??!?!?"
    Last edited by SlyMaelstrom; 02-13-2006 at 03:54 PM.
    Sent from my iPadŽ

  3. #3
    Registered User
    Join Date
    Feb 2006
    Posts
    6
    Um, I know how scanf works (the basics anyways, with %d and %s), but I'm only allowed to use %c.

  4. #4
    Devil's Advocate SlyMaelstrom's Avatar
    Join Date
    May 2004
    Location
    Out of scope
    Posts
    4,079
    Ok, so it's an assignment restriction. That wasn't well clarified. What you want to do is flush the input buffer when it prints the error message.

    Code:
    else {
       printf("Incorrect option.\n");
       while ((junkchar = getchar()) != '\n' && junkchar != EOF);
       printMenu();
    }
    ...and if this is an assignment restriction, then what does this mean?

    as I'm not sure how C actually does this.
    Last edited by SlyMaelstrom; 02-13-2006 at 04:21 PM.
    Sent from my iPadŽ

  5. #5
    Registered User
    Join Date
    Feb 2006
    Posts
    6
    Sorry for being unclear, I meant that I wasn't sure how C handled scanf with %c if in a while loop (guess I was being pretty vague). Can you explain how that extra line you added works? Also, are junkchar and ch supposed to be two new characters and, if so, what do they represent within the program?

  6. #6
    Devil's Advocate SlyMaelstrom's Avatar
    Join Date
    May 2004
    Location
    Out of scope
    Posts
    4,079
    Code:
    while ((junkchar = getchar()) != '\n' && junkchar != EOF);
    Sorry ch should also be junkchar and yes, that's a new character. What this loop does is continues to take a character from the input buffer and store it into junkchar until junkchar equals a newline character or an end of file character.

    Let's say someone types in a few characters:

    > a78dfg\n

    Your scanf reads the 'a', gets to the else condition, gives the error message and gets to the loop.

    7 goes into junkchar, meets the condition of not being a \n or EOF, and it loops. 8 goes into junkchar... and so on and so on until it reads in the \n. The condition returns false, it exits the loop and prints the menu. Once.

    Now here is the deal: You'll probably want to flush the buffer right before the scanf. This way if someone types '5ag' and it goes to option '5'. It doesn't print the menu three times.
    Last edited by SlyMaelstrom; 02-13-2006 at 04:29 PM.
    Sent from my iPadŽ

  7. #7
    Registered User
    Join Date
    Feb 2006
    Posts
    6
    It looks like it's working just fine, thank you very much! One last thing, that line could also be used to read whole lines as input, if the junkchar was changed to a meaningful variable right?

  8. #8
    Devil's Advocate SlyMaelstrom's Avatar
    Join Date
    May 2004
    Location
    Out of scope
    Posts
    4,079
    Sure, ofcourse you'd have to identify each digit one at a time. For instance, let's say you read in a '1'. Now this could be a 1 or if you kept reading it might be a 10 or 11... unfortunately if you were to read in another value and it's say... a newline character. Then you lost your one and you'll end up with an invalid input error. Either use multiple variables, or your could just blow off your teacher and use strings.
    Sent from my iPadŽ

  9. #9
    User
    Join Date
    Jan 2006
    Location
    Canada
    Posts
    499
    I know this really doesn't have much to do with your problem, but it makes your code much. much neater. Use a switch statement instead of all those ifs and else ifs like this:

    Code:
    switch(command) {
    
       case 1:
       // ....
       break;
    
       case 2:
       // ....
       break;
    
       case default:
       //invalid option
    }

  10. #10
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Sorry ch should also be junkchar and yes, that's a new character.
    You meant, "yes, that's a new int", right? EOF is an int value.
    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.

  11. #11
    Devil's Advocate SlyMaelstrom's Avatar
    Join Date
    May 2004
    Location
    Out of scope
    Posts
    4,079
    'course that's what I meant... I was just testing you dwks.
    Sent from my iPadŽ

  12. #12
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Of course . . . never mind that I wasn't logged in.

    Code:
    void main()
    Use int main(), not void: http://faq.cprogramming.com/cgi-bin/...&id=1043284376

    Here is the relevant FAQ for getting numbers from the user: http://faq.cprogramming.com/cgi-bin/...&id=1043284385
    Look at the last program in Option 3 and add an EOF check in the buffer-flushing loop.
    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.

  13. #13
    Registered User
    Join Date
    Feb 2006
    Location
    Philadelphia, PA
    Posts
    27
    As far as I know, you can use multiple %c%c%%c etc.... to get as many characters at once as you want. You'll have to define them later.

  14. #14
    Devil's Advocate SlyMaelstrom's Avatar
    Join Date
    May 2004
    Location
    Out of scope
    Posts
    4,079
    Quote Originally Posted by ademkiv
    As far as I know, you can use multiple %c%c%%c etc.... to get as many characters at once as you want. You'll have to define them later.
    That's not such a good idea if say someone actually wanted a choice with a one digit number.
    Sent from my iPadŽ

  15. #15
    Registered User
    Join Date
    Feb 2006
    Location
    Philadelphia, PA
    Posts
    27
    true, i didn't think of it before.
    I guess you can try to get one digit at a time, and lets say define "999" to be abort code. When user enters "999" program goes to the next step and does the calculations.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. scanf() consideres useless
    By Snafuist in forum C Programming
    Replies: 15
    Last Post: 02-18-2009, 08:35 AM
  2. Help with a basic scanf procedure.
    By killpoppop in forum C Programming
    Replies: 9
    Last Post: 11-03-2008, 04:39 PM
  3. scanf issue
    By fkheng in forum C Programming
    Replies: 6
    Last Post: 06-20-2003, 07:28 AM
  4. Scanf and integer...
    By penny in forum C Programming
    Replies: 3
    Last Post: 04-24-2003, 06:36 AM
  5. scanf - data is "put back" - screws up next scanf
    By voltson in forum C Programming
    Replies: 10
    Last Post: 10-14-2002, 04:34 AM