Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie

menu based C program

Options
  • 06-11-2005 9:40pm
    #1
    Registered Users Posts: 26,578 ✭✭✭✭


    hey guys,

    i've only been learning C now for about a month and a bit so bear with me.

    what i'm trying to is build a program that is based on a menu like this.

    1. option 1.
    2. option 2.
    3. option 3.
    4. option 4.
    5. option 5.

    etc, etc.

    now i've used a do-while loop for what i need done.

    i've stuck an if statement like this
    if (value_entered > 5)
       {
          printf("ERROR, Please try again") ; 
       }
    


    but my problem comes around when say the user enters .1 or something that isn't an int, what ever code that is in the do-while loop gets executed in an infinite loop.

    is there any way to stop this say if a user enters a float or a char or a string


Comments

  • Closed Accounts Posts: 4,943 ✭✭✭Mutant_Fruit


    while(1) //infinite loop, change as needed:
    {
      printf("Enter your number");
      scanf("%d", &entered_number);
      
      if(entered_number == 1)
        {
        }
      
      else if(entered_number == 2)
        {
        }     
      else if(entered_number == 5)
        {
        }
      
      else
        {
          printf("Enter a real number");
        }
      entered_number = -1;
    }
    

    Just remember to reset the number after each loop. The important thing here is that you first account for every acceptable input using if's and else if's, then finally your "else" statement will print out the message saying it got an invalid input. If it isn't picked up by the if's or else if's, its invalid.

    Of course, after each loop you're always best resetting those variables. I know strictly speaking you don't have to reset entered_number to -1, but i've seen a good few programs go wrong because numbers havn't been reset when they should be. So make a point of resetting it to -1 or something impossible whenever you're sure its out of date.


  • Closed Accounts Posts: 3,783 ✭✭✭Binomate


    Wouldn't it be easier to do a switch statment?


  • Registered Users Posts: 15,443 ✭✭✭✭bonkey


    Cremo wrote:
    hey guys,
    now i've used a do-while loop for what i need done.

    What's your loop condition?
    Or are you using an infinite loop ( while(true) ) and breaking out of it?
    but my problem comes around when say the user enters .1 or something that isn't an int, what ever code that is in the do-while loop gets executed in an infinite loop.
    Your if statement isn't causing that.

    Without more of the code in the loop, its pretty impossible to tell you what you're doing wrong.
    is there any way to stop this say if a user enters a float or a char or a string

    Yes. You set a condition to allow you to leave the loop - or break - when the value is valid. .

    jc


  • Closed Accounts Posts: 82 ✭✭cyberbob


    i think what he is lookin for is somethin like this :
    (excuse the lack of code tags )

    // ie scanf will fail trying to put value_entered
    // into a %d type place holder if its not an interger

    if scanf( "%d" , value_entered) != 1

    {
    printf ( "enter a number ffs !" );
    }
    else
    {
    }


  • Closed Accounts Posts: 4,943 ✭✭✭Mutant_Fruit


    Binomate wrote:
    Wouldn't it be easier to do a switch statment?
    Aye, but i wasn't sure if he had covered it already or not, so i didn't bother.

    what ever code that is in the do-while loop gets executed in an infinite loop.
    Post up the code before and after the do-while section so we can tell you WHY it loops forever with an invalid entered_number. Or maybe you could tell us why... :P


  • Advertisement
  • Registered Users Posts: 26,578 ✭✭✭✭Creamy Goodness


    ok here's the code from the end of the do-while loop
    main()
    {
         //basically the only part of code before do-while is variable declaration
    
         int selection ; 
         
    
          do
          {
           // at the end of the loop i wrote this
           if (selection > 5)
              printf("error, try again") ;
          }
          while (selection != 5) ;
          
          if(selection == 5)
          {
                 printf("program terminated\n") ;
                 printf("Good bye!\n") ;
          }
          
    getchar() ;
    return 0 ;
    
    }
    
    
    bonkey wrote:
    What's your loop condition?
    Or are you using an infinite loop ( while(true) ) and breaking out of it?
    i'm not using a while(true) loop i think.

    i know how to do switch which i should of really done, i'll probably will do aswell it shouldn't take that long to re-edit the code

    if you need anymore info please ask. :v:


  • Closed Accounts Posts: 4,943 ✭✭✭Mutant_Fruit


    Theres only so much i can say without going out and out and correctly your program...

    Firstly, getchar() returns a character. If you want to use that, you'll need to #include <stdlib.h> and use the atoi() function to convert that character to an integer. My advice, just use a scanf() type jobby to read in an integer.

    Secondly, look at your do-while loop? What exactly is happening every time that loops. Trace it out with your mind. You should easily spot the problem.

    Thirdly, fix all your clauses (such as the if statements, while() statements etc). Trace out what would happen for each number from 1-5. You'll see some cases are impossible/don't make sense.


  • Closed Accounts Posts: 3,783 ✭✭✭Binomate


    Cremo, have you done the main part of your code(Currency Converter) yet or are you working on the menus first and editing the code into that?


  • Registered Users Posts: 26,578 ✭✭✭✭Creamy Goodness


    yeh, i've basically written the whole code for everything.

    everything validates right but it's just when you enter a float number or a character when asked to select from 1-5 the program does a continous loop and keeps going for infinity.


  • Registered Users Posts: 6,508 ✭✭✭daymobrew


    I would read in a string with gets() or something similar and then atoi() it.
    atoi() will return 0 if the data is not an integer. As this is not a valid choice it'll invoke your error code.
    The person can enter whatever they like and it won't kill your program.


  • Advertisement
  • Registered Users Posts: 5,335 ✭✭✭Cake Fiend


    A switch statement with cases for any valid input and a default case that catches anything else (invalid) will do the job nicely. No need to make it any more complicated than it needs to be.


  • Moderators, Recreation & Hobbies Moderators, Science, Health & Environment Moderators, Technology & Internet Moderators Posts: 91,692 Mod ✭✭✭✭Capt'n Midnight


    You could round off the input (after verifying it's a number)

    If you are only looking for a number between 0-9 then you may be better off just working from a keypress, rather than input anything ended by enter/return

    http://gd.tuwien.ac.at/languages/c/programming-bbrown/c_030.htm
    [php] #include <stdio.h>

    main()
    {
    int i;
    int ch;

    for( i = 1; i<= 5; ++i ) {
    ch = getchar();
    putchar(ch);
    }
    }[/php]


  • Closed Accounts Posts: 4,943 ✭✭✭Mutant_Fruit


    He's only new at this. Don't confuse him with a dozen ways to do it :P I'd say at his level he's good at using printf's and scanf's, so thats why i'd recommend he stick to that.

    For this, scanf(%d....); would be the best method. Put that in a while loop and get it to keep scanning the input until you get a valid value. Simple stuff!

    To check for a valid value, just check the return value == 1. i.e.

    printf("Enter your number");

    while(scanf("%d", &entered_number) != 1)
    {
    printf("Enter a valid number please");
    }


  • Registered Users Posts: 6,508 ✭✭✭daymobrew


    He's only new at this. Don't confuse him with a dozen ways to do it :P I'd say at his level he's good at using printf's and scanf's, so thats why i'd recommend he stick to that.
    Yes he's new, but he is showing initiative wrt handling invalid data so I think we should help. It's a topic close to my heart because I tried to do the same thing when I was learning C.
    Writing solid code is always commendable.
    printf("Enter your number");
    while(scanf("%d", &entered_number) != 1)
    {
      printf("Enter a valid number please");
    }
    
    Unfortunately this becomes an infinite loop if a non-numeric char/string is entered, as Creamo as discovered.
    #include <stdarg.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    void main( void )
    {
      char szInput[200];
      int i;
    
      do
      {
        scanf( "%s", szInput ); /* gets() or fgets() also possible */
        i = atoi( szInput );
        /* i==0 if szInput is not numeric. */
        printf ("i = %d\n", i );
      } while ( i != 5 );
    }
    
    i will be 0 if the entered string is not numeric. 0 is not a valid choice so the default clause in the switch statement (as suggested by Sico) will catch this.

    Looking at the site linked by Capt N'Midnight, it recommends using getchar and atoi to workaround the 'scanf' infinite loop problem.


  • Registered Users Posts: 15,443 ✭✭✭✭bonkey


    daymobrew wrote:
    printf("Enter your number");
    while(scanf("%d", &entered_number) != 1)
    {
      printf("Enter a valid number please");
    }
    
    Unfortunately this becomes an infinite loop if a non-numeric char/string is entered, as Creamo as discovered.

    Maybe I'm missing something here, but I don't see how this forms an infinite loop, unless the user enters invalid data on each seperate iteration.

    Thats not quite the same as Creamo's code, which will enter an infinite loop subsequent to a single validation failing.

    In other words, the original code was "test once, loop infinitely on fail with no subsequent restesting". The code you're saying is the same is "loop, testing on each iteration until you don't fail".

    It may not be an ideal solution, but its not correct to say its prone to the same problem.

    jc


  • Closed Accounts Posts: 4,943 ✭✭✭Mutant_Fruit


    Unfortunately this becomes an infinite loop if a non-numeric char/string is entered, as Creamo as discovered.
    No, the difference in my code is that the when the "while" condition is evaluated, the program tries to scan in a number, if there is no number there or if the number is invalid, it'll print the message, and then wait for a new number ot be entered. Tis (in my opinion) the perfect solution. Its impossible for the program to procede until a valid integer is entered. This is the behavior he wants.

    Reading in a float and rounding up wouldn't be a good way to do it, simply because a float is not a valid input. He could set a default behavior (such as always run option 1 if the entered input is invalid) but you should never manually change input in that way without a good reason.


  • Registered Users Posts: 6,508 ✭✭✭daymobrew


    bonkey wrote:
    Maybe I'm missing something here, but I don't see how this forms an infinite loop, unless the user enters invalid data on each seperate iteration.

    Thats not quite the same as Creamo's code, which will enter an infinite loop subsequent to a single validation failing.
    Yes, I quoted the wrong code. I had a few small test programs and copied the wrong one.
    The following code goes into an infinite loop if you enter a non-numeric char:
    #include <stdarg.h>
    #include <stdio.h>
    
    void main( void )
    {
      int i;
      do
      {
        scanf( "%d", &i );
        printf ("i = %d\n", i );
      } while ( i != 5 );
    }
    
    while(scanf("%d", &entered_number) != 1)
    
    Nice one. Testing the return value of scanf is a great idea.


  • Closed Accounts Posts: 4,943 ✭✭✭Mutant_Fruit


    daymobrew wrote:
    Nice one. Testing the return value of scanf is a great idea.
    Aye, thats why we have return values! We have em to test for a successful completion of the task! So, bear that in mind whenever you write a function, always make sure that an intelligent value is returned when an error occurs, and a logical one returns when it's successful.

    If i ran a scanf("%d %s %f", &integervalue1, &stringvalue2, &floatvalue3) the return value would be 3 if it managed to scan in all three values (a handy trick for reading in values).


  • Closed Accounts Posts: 82 ✭✭cyberbob


    Aye, thats why we have return values! We have em to test for a successful completion of the task! So, bear that in mind whenever you write a function, always make sure that an intelligent value is returned when an error occurs, and a logical one returns when it's successful.

    If i ran a scanf("%d %s %f", &integervalue1, &stringvalue2, &floatvalue3) the return value would be 3 if it managed to scan in all three values (a handy trick for reading in values).

    it was my idea if you scroll up.
    sheesh.... slow news day if this one got so many replies...


Advertisement