Thread: I need help with validation for two inputs

  1. #1
    Registered User
    Join Date
    Dec 2007
    Posts
    13

    I need help with validation for two inputs

    Hello, I am having trouble with error checking on my program that has two inputs. The first is a menu selection, and the second is an amount greater than 0. For both inputs it must check against entering a letter or an invalid number. I tried a do/while statement for the menu selection, and that took care of the valid menu option part, but I can't seem to figure out how to handle a character input.

    I tried to use isdigit to solve this problem, but I may not have implemented it correctly. If you guys could take a look at my code and maybe give some advice on what would be the best way to tackle this problem.

    Code:
    #include <stdio.h>
    #include <ctype.h>
    
    	main()
    	
    	 {
    	 	char iSelection;
    	 	float fCurrSelect = 0.00;
    	 	float fUSCurr = 0.00;
    	 	
    	 do {
    	 	
    	 	printf("\n\tCurrency Conversion Program 1.1\n\n");
    	 	printf("\nChoose the currency you wish to convert\n");
    	 	printf("\n1\tAustrailian dollar");
    	 	printf("\n2\tCanadian dollar");
    	 	printf("\n3\tEuro");
    	 	printf("\n4\tMexican peso");
    	 	printf("\n5\tSwiss franc\n\n");
    	 	scanf("%d", &iSelection);
    	 		
    	 	} while (iSelection < 1 || iSelection > 5);  
    	 	 	   
    	 
    	 	printf("\nHow much money would you like to convert to U.S. dollars?");
    	 	scanf("%f", &fCurrSelect);
    	 	   
    	 	  
    	 	   
    	 	   
    	 	switch(iSelection) {
    	 	   
    	 	      case 1:
    	 	      fUSCurr = (fCurrSelect/1.16686);
    	 	      printf("\nThe Austrailian dollar amount %.2f converted to USD equals $%.2f", fCurrSelect, fUSCurr);
    	 	      break;
    	 	      
    	 	      case 2:
    	 	      fUSCurr = (fCurrSelect/1.0072);
    	 	      printf("\nThe Canadian dollar amount %.2f converted to USD equals $%.2f", fCurrSelect, fUSCurr);
    	 	      break;
    	 	      
    	 	      case 3:
    	 	      fUSCurr = (fCurrSelect/0.695943);
    	 	      printf("\nThe Euro amount %.2f converted to USD equals $%.2f", fCurrSelect, fUSCurr);
    	 	      break;
    	 	      
    	 	      case 4:
    	 	      fUSCurr = (fCurrSelect/10.8509);
    	 	      printf("\nThe Mexican peso amount %.2f converted to USD equals $%.2f", fCurrSelect, fUSCurr);
    	 	      break;
    	 	      
    	 	      case 5:
    	 	      fUSCurr = (fCurrSelect/1.1522);
    	 	      printf("\nThe Swiss franc amount %.2f converted to USD equals $%.2f", fCurrSelect, fUSCurr);
    	 	      break;
    	 	      
    	 	      default:
    	 	      printf("\nInvalid option!");
    	 	      
    	 	   }//end switch block
    	 	   getchar();
    	  }//end main

  2. #2
    Registered User
    Join Date
    Sep 2006
    Posts
    230
    Your code is not indented correctly. Please correct it (you have an error where the do... while loop ends.

  3. #3
    Registered User
    Join Date
    Sep 2006
    Posts
    230
    Here's the new indented code with some corrections (int main(), return 0):
    Code:
    #include <stdio.h>
    #include <ctype.h>
    
    int main(void)
    {
    	char iSelection;
    	float fCurrSelect = 0.00;
    	float fUSCurr = 0.00;
    	 	
    	do 
    	{
    		printf("\n\tCurrency Conversion Program 1.1\n\n");
    	 	printf("\nChoose the currency you wish to convert\n");
    	 	printf("\n1\tAustrailian dollar");
    	 	printf("\n2\tCanadian dollar");
    	 	printf("\n3\tEuro");
    	 	printf("\n4\tMexican peso");
    	 	printf("\n5\tSwiss franc\n\n");
    	 	scanf("&#37;d", &iSelection);
    	} while (iSelection < 1 || iSelection > 5);  
    	 	 	   
    	 
    	printf("\nHow much money would you like to convert to U.S. dollars?");
    	scanf("%f", &fCurrSelect);
    		 	   
    	 	   
    	switch(iSelection) 
    	{
    		case 1:
    	 		fUSCurr = (fCurrSelect/1.16686);
    	 		printf("\nThe Austrailian dollar amount %.2f converted to USD equals $%.2f", fCurrSelect, fUSCurr);
    	 		break;
    	 	      
    	 	case 2:
    	 		fUSCurr = (fCurrSelect/1.0072);
    	 		printf("\nThe Canadian dollar amount %.2f converted to USD equals $%.2f", fCurrSelect, fUSCurr);
    	 		break;
    	 	      
    	 	case 3:
    	 		fUSCurr = (fCurrSelect/0.695943);
    	 		printf("\nThe Euro amount %.2f converted to USD equals $%.2f", fCurrSelect, fUSCurr);
    	 		break;
    	 	      
    	 	case 4:
    	 		fUSCurr = (fCurrSelect/10.8509);
    	 		printf("\nThe Mexican peso amount %.2f converted to USD equals $%.2f", fCurrSelect, fUSCurr);
    	 		break;
    	 	      
    	 	case 5:
    	 		fUSCurr = (fCurrSelect/1.1522);
    	 		printf("\nThe Swiss franc amount %.2f converted to USD equals $%.2f", fCurrSelect, fUSCurr);
    	 		break;
    	 	      
    	 	default:
    	 		printf("\nInvalid option!");
    	}//end switch block
    	getchar();
    	return 0;
    }//end main
    Now I can actually take a look at the code!

  4. #4
    Registered User
    Join Date
    Sep 2006
    Posts
    230
    I don't see any characters being input. The only 2 inputs are the option (as an int) and the monetary value (as a float).
    You are declaring iSelection as a char, but you're using scanf to input an integer value into it. If you want to use it as a char I suggest you use getchar() and assign iSelection to it. However, you will need to change the cases in the switch statement to chars ('1' instead of 1).

    EDIT: By the way I don't see any errors in your code. I even tried compiling it and testing it and it worked fine. What was your problem with it?
    Last edited by Abda92; 12-19-2007 at 12:41 PM.

  5. #5
    Registered User
    Join Date
    Dec 2007
    Posts
    13
    Sorry about the indentation, as you can tell I am rather new to this I forgot to switch back the iSelection to int after messing with it. I was trying the isdigit to verify that a digit was entered. The problem that I am having is that we are suppose to have the input checked to make sure that someone doesn't enter a letter, and for the monetary value it should be greater than 0 and not be a letter. When you enter a letter it just loops infinitely, obviously due to the fact I have no error check for this.

    I would think that isdigit should fix the problem, but I am not sure how to add that in properly. I tried to add it in with my while statement, but it didn't seem to do anything. Thanks for the replies guys, I really appreciate the help.

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Because you're telling scanf to read an int with &#37;d. And if you enter a non-int, well... then it fails.
    What you can do is read a char with %c (or a string with %s, but that's slightly more complex) and then check if it's a digit or not.
    The usual approach I do is to do a conversion of the number with atoi. Then I simply check if atoi returns 0, and if it does, did the user enter a '0'? If not, then obviously it's not a number (because atoi returns 0 on failure).
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    There are two general methods for dealing with "incorrect input". One is to use scanf() and check if the return value matches the number of % items, e.g. scanf("%d", &a) should return 1, scanf("%f %f", &x, &y) should return 2. If it doesn't you need to read away any input up until the next newline, and try again.

    The other main alternative is to use a "line read" function, typically fgets() and then use either sscanf() [again checking the return value] or functions like "strtol" and "strtod" - or your own functions to check the content for various "parts", and then once you've ascertained that the string is OK, you pass it through one of the above mentioned functions.

    The advantage of fgets() method is that you don't have to deal with "leftover stuff in the input buffer", which you need to deal with in the first case.

    --
    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.

  8. #8
    Registered User
    Join Date
    Dec 2007
    Posts
    13
    Thank you so much for the replies guys. We never really covered anything about error handling in our text, and the teacher is not so speedy with getting back to us with questions. I like how we get assignments that are more advanced than the material that we cover I guess I will have to do some research on fgets, strtol, and strtod. Thanks again!

  9. #9
    Registered User
    Join Date
    Dec 2007
    Posts
    13
    Ok, I have tried some new things and I think I am getting close. I used an if statement and it seems to check the validation of the entry. The only thing is that when a valid entry is made, it goes right to the calculation part of my code, and skips the second input part.

    I am also not sure how to return back to the menu selection after a choice has been made, the program just finishes either way. Here is the updated code:

    Code:
    #include <stdio.h>
    #include <ctype.h>
    
    	main()
    	
    	 {
    	 	char iSelection = '\0';
    	 	float fCurrSelect = 0.00;
    	 	float fUSCurr = 0.00; 	
    	 	 	
    	 	printf("\n\tCurrency Conversion Program 1.1\n\n");
    	 	printf("\nChoose the currency you wish to convert\n");
    	 	printf("\n1\tAustrailian dollar");
    	 	printf("\n2\tCanadian dollar");
    	 	printf("\n3\tEuro");
    	 	printf("\n4\tMexican peso");
    	 	printf("\n5\tSwiss franc\n\n");
    	 	scanf("%c", &iSelection); 		
    	   	 	 	   
    	 	if (isdigit(iSelection)&& iSelection >= 1 && iSelection <= 5){
    	 	printf("\nHow much money would you like to convert to U.S. dollars?");
    	 	scanf("%f", &fCurrSelect);
    	 		 	
    	 	}//end if statement 
    	 	   
    	 	switch(iSelection) {
    	 	   
    	 	      case '1':
    	 	      fUSCurr = (fCurrSelect/1.16686);
    	 	      printf("\nThe Austrailian dollar amount %.2f converted to USD equals $%.2f", fCurrSelect, fUSCurr);
    	 	      break;
    	 	      
    	 	      case '2':
    	 	      fUSCurr = (fCurrSelect/1.0072);
    	 	      printf("\nThe Canadian dollar amount %.2f converted to USD equals $%.2f", fCurrSelect, fUSCurr);
    	 	      break;
    	 	      
    	 	      case '3':
    	 	      fUSCurr = (fCurrSelect/0.695943);
    	 	      printf("\nThe Euro amount %.2f converted to USD equals $%.2f", fCurrSelect, fUSCurr);
    	 	      break;
    	 	      
    	 	      case '4':
    	 	      fUSCurr = (fCurrSelect/10.8509);
    	 	      printf("\nThe Mexican peso amount %.2f converted to USD equals $%.2f", fCurrSelect, fUSCurr);
    	 	      break;
    	 	      
    	 	      case '5':
    	 	      fUSCurr = (fCurrSelect/1.1522);
    	 	      printf("\nThe Swiss franc amount %.2f converted to USD equals $%.2f", fCurrSelect, fUSCurr);
    	 	      break;
    	 	      
    	 	      default:
    	 	      printf("\nInvalid option!");
    	 	      
    	 	   }//end switch block
    	 	   getchar();
    	 	   return 0;
    	  }//end main

  10. #10
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Code:
    if (isdigit(iSelection)&& iSelection >= 1 && iSelection <= 5)
    The call to isdigit will be true for "iSelection" being 48 ('0') to 57 ('9') - so you never get a true here.

    Also, if you use the "greater/less than" method, you can be sure that it's a digit, because ALL of the known number representations are contiguous - by that, I mean there is nothing BETWEEN 0..9 that isn't a digit, so if you check the range, you don't actually need "isdigit".

    You probably want to use some sort of loop to make sure you ask again if the answer is NOT what you wanted.

    --
    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.

  11. #11
    Registered User
    Join Date
    Dec 2007
    Posts
    13
    Ah, I guess I didn't know that about the isdigit function. I think I am one step closer to getting this program to where I like it. I chose to go back with the do/while statement, and I also added a do/while for the monetary value entered. It now checks for letters and invalid digits. The only weird thing is that it seems like the menu loops twice when a wrong input is given. Here is just the part of the code that I was having trouble with, I am sorry for cluttering up the thread:

    Code:
    int main(void)
    	
    	 {
    	 	char iSelection = '\0';
    	 	float fCurrSelect = 0.00;
    	 	float fUSCurr = 0.00;
    	 	
    	 	do { 	
    	 	 	
    	 	printf("\n\tCurrency Conversion Program 1.1\n\n");
    	 	printf("\nChoose the currency you wish to convert\n");
    	 	printf("\n1\tAustrailian dollar");
    	 	printf("\n2\tCanadian dollar");
    	 	printf("\n3\tEuro");
    	 	printf("\n4\tMexican peso");
    	 	printf("\n5\tSwiss franc\n\n");
    	 	scanf("%c", &iSelection); 		
    	   	 	 	   
    	 	}while ( iSelection < '1' || iSelection > '5');
    	 	
    	 	do {
    	 	printf("\nHow much money would you like to convert to U.S. dollars?");
    	 	scanf("%f", &fCurrSelect);
    	 	}while (fCurrSelect <= 0.0);
    I will work on having an exit type so that the user may continue to use the program without having to re-run it. Would a flag be used in that sort of situation?

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by KarrieWojo View Post
    Code:
    int main(void)
    	
    	 {
    	 	char iSelection = '\0';
    	 	float fCurrSelect = 0.00;
    	 	float fUSCurr = 0.00;
    	 	
    	 	do { 	
    	 	 	
    		 	printf("\n\tCurrency Conversion Program 1.1\n\n");
    		 	printf("\nChoose the currency you wish to convert\n");
    	 		printf("\n1\tAustrailian dollar");
    		 	printf("\n2\tCanadian dollar");
    			printf("\n3\tEuro");
    		 	printf("\n4\tMexican peso");
    		 	printf("\n5\tSwiss franc\n\n");
    		 	scanf("&#37;c", &iSelection); 		
    	   	 	 	   
    	 	}while ( iSelection < '1' || iSelection > '5');
    	 	
    	 	do {
    		 	printf("\nHow much money would you like to convert to U.S. dollars?");
    		 	scanf("%f", &fCurrSelect);
    	 	}while (fCurrSelect <= 0.0);
    Indent the code like so, please. Every block should be indented once.
    You may not consider this important, but I assure you it is. It makes the code readable. No one wants to go poorly indented code to look for mistakes. So following a basic set of rules will make it much easier for us, as for you.
    Your problem? When you type "0", you actually type '0' + '\n', so the '\n' is left in the buffer, so when you loop it reads the newline character and treats it as wrong and re-loops.
    The solution might be to read another char using getchar().

    In case you want to exit, just add another selection to the menu and check if c == '6' or something, then exit. Easiest way.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  13. #13
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Code:
                    do {
    		 	printf("\nHow much money would you like to convert to U.S. dollars?");
    		 	scanf("%f", &fCurrSelect);
    	 	}while (fCurrSelect <= 0.0);
    If someone enter "abc" or some such, it will be accepted, because you don't check the result of scanf(). [Or it WON'T be accepted if the previously entered value was negative].

    There is also no possibility to ever enter a new value in that case, as the input buffer will now hold "abc", which is non-numeric, so any further scanf call for a numeric value will fail.

    --
    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.

  14. #14
    Registered User
    Join Date
    Dec 2007
    Posts
    13
    Thank you so much matsp for the replies. It seems as if once I figure one thing out, there is a plethora of more things right inside of it to confuse me I will have to try some more tweaking and experimenting to see what I can come up with.

    Also, how would I have an error message shown if the user makes a wrong selection. I am guessing that it would have to be inside the do/while block because if it is outside it just prints the error message when a valid entry is made. I will play around with this for a bit too, and see what I get.

  15. #15
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Yes, the error message would go inside the do-while loop. It probably makes most sense if you create a local variable to track if the input is accepted or not, and when you see an incorrect input, you set the flag to say "not valid". That way, you don't have two checks to see if the input is valid.

    --
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. c++ validation
    By rahulsk1947 in forum C++ Programming
    Replies: 4
    Last Post: 06-08-2009, 01:53 PM
  2. How do I validate these inputs?
    By Kyeong in forum C Programming
    Replies: 1
    Last Post: 10-19-2008, 02:20 PM
  3. checking inputs meets multiple conditions
    By 60beetle60 in forum C Programming
    Replies: 5
    Last Post: 04-19-2008, 08:25 AM
  4. set validation
    By jmarsh56 in forum C++ Programming
    Replies: 4
    Last Post: 12-13-2005, 08:49 AM
  5. [C#] Validation class for events?
    By gicio in forum C# Programming
    Replies: 4
    Last Post: 01-03-2003, 12:19 PM