Lost Password?

Go Back   CodeCall Programming Forum > Software Development > C and C++

C and C++ C and C++ forum for discussing all forms of C except for C#. These languages are powerful low level languages used for creating Operating Systems, Device Drivers, compilers and much more.

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
  #1 (permalink)  
Old 07-03-2007, 06:39 PM
Xochiquetzal Xochiquetzal is offline
Newbie
 
Join Date: Jun 2007
Posts: 5
Rep Power: 0
Xochiquetzal is on a distinguished road
Default [C++] Validating user input

'ay!
Most of the programs I write are very dependent on user input (using your own programs = fun!). As such I've been googling lately for a way to validate what users write. I've found nothing that I can understand...

I just made a simple game ("guess the random number between 0 and 100 in 10 tries"). The user is supposed to input an integer (stored in the guess variable). The program bugs out if one inputs anything else (including floats), by spamming the "It's higher..." switch case. This is pretty likely a result of the program structure (it seems odd, can't put my finger on exactly what), but until I know how to improve that -- what I should do to validate that the input is an integer?

Here's my code for reference. The input-section is right after the big "The game" comment chunk.

Code:
#include <iostream>
#include <time.h>		// for rng seed

int main() {
	
	// VARIABLE INITALIZATION
	
	srand((unsigned)time(0));	// rng seed
	int number = rand()%101;	// the random number between 0-100; raN
	int guess,numberOfGuesses=0;
	std::string guessCount[10] = {
	"First", "Second", "Third", "Fourth",	// first [guess], second [guess]...
	"Fifth", "Sixth", "Seventh", "Eighth",	// represents numberOfGuesses
	"Ninth", "Tenth (last!!)" };
	
	// INTRODUCTION TO GAME
	
	std::cout << "Welcome to Xochi's Number Game!!"	<< std::endl
		<< "I have a random number between 0 and 100." << std::endl
		<< "You must try to find it within 10 tries!!\n" << std::endl;
		// introduction
	
	// THE GAME
	
	// 	the guess loop - while the number of guesses is lower than 10,
	//	it goes through this do{}: enter a number -> is guess == raN?
	//	if yes, go to else (game quit)
	//	if no, is raN<guess? write whether it is lower/higher,
	//	then go to the loop start.
	//	when numberOfGuesses==10, go to next do-loop
							
	do {
		numberOfGuesses++;	// that's one guess
		if(numberOfGuesses==10) std::cout << "\a";	// last try beep warning
		std::cout << "Enter your guess! "
		<< guessCount[numberOfGuesses-1] << " try:" << std::endl;
		// gC[nOG-1]: -1 needed due to 1st in array = [0]
		std::cin >> guess;	// input >> int guess
		// here, I need some way of validating that guess==int!


		// GUESS==RAN CHECKS AND PROCEDURES
		
		if(guess!=number) {	// guess != raN
			switch((number<guess)?1:0) {	
			// 1 = guess is lower than raN
				case 1:
				std::cout << "It's lower...\n" << std::endl;
				break;		// go to loop start, new guess
				case 0:
				std::cout << "It's higher...\n" << std::endl;
				break;		// go to loop start, new guess
				}
			}
		else {	// guess==raN;
		//exit message depends on how many tries it took to find raN
			if(numberOfGuesses==1) {
			std::cout << "Whoaaaw!! First try! That's really great!!";
			// impressive!
			exit(0); // normal program termination
				}

			else if(numberOfGuesses==2 || numberOfGuesses==3) {	
			std::cout << "You found it! It took you "
			<< numberOfGuesses << " tries." << std::endl
			<< "That's pretty nice!!" << std::endl;
			exit(0);
				}

			else if(numberOfGuesses==4 || numberOfGuesses==5) {
			std::cout << numberOfGuesses
			<< " tries! Good!" << std::endl;
			exit(0);
				}

			else if(numberOfGuesses==6 || numberOfGuesses==7) {
			std::cout << numberOfGuesses
			<< " tries... kinda average!" << std::endl;
			exit(0);
				}

			else if(numberOfGuesses==8) {
			std::cout << "8 tries eh? That's kinda lousy..." << std::endl;
			exit(0);
				}

			else if(numberOfGuesses==9) {
			std::cout << "9 tries?! That's actually terrible! Go practice even more!!"
			<< std::endl;
			exit(0);
				}
		}
	} while(numberOfGuesses!=10);
	// repeat this guess-loop until the number of guesses==10
	
	// RAN WASN'T FOUND AFTER 10 TRIES!
	
	do {	// when the number of guesses == 10 and raN not found
		std::cout << "10 tries and no match! The number was " << number
		<< ".\nPractice more and return!" << std::endl;
		exit(0); // normal program termination
	} while(numberOfGuesses==10);

	return 0;
}
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote

Sponsored Links
  #2 (permalink)  
Old 07-04-2007, 01:22 AM
v0id's Avatar   
v0id v0id is offline
Super Moderator
 
Join Date: Apr 2007
Location: Denmark
Posts: 2,452
Last Blog:
CherryPy(thon)
Rep Power: 27
v0id is a glorious beacon of lightv0id is a glorious beacon of lightv0id is a glorious beacon of lightv0id is a glorious beacon of lightv0id is a glorious beacon of lightv0id is a glorious beacon of light
Send a message via MSN to v0id
Default

It's generally a bad idea to use std::cin all alone. One of the most used ways to get user input, no matter type is to use strings, stringstreams and the resulting type. We can make a template function, to do this for us.
Code:
template<typename Type>
bool GetInput(Type &destination, std::istream &stream = std::cin)
{
	std::string temporaryHolder;
	std::stringstream stringStream;
	
	std::getline(stream, temporaryHolder);
	stringStream << temporaryHolder;
	
	return (stringStream >> destination);
}
This function accepts user input of any kind. You can use it with integers, floating numbers, strings, and so on. That's because that the stringstream can "convert" with these types. First we're getting the user input, exactly as it was typed, into a string. Secondly, we're giving the string to the stringstream. Thirdly, we're sending it from the stringstream to the variable the user specified. The second parameter in the function, is simply the stream to get input from - in our example std::cin, because we want user input. It could had been a file stream too.

If you then want to use the function, it's a lot easier, and you don't need to do much. F.ex. if we want to get an integer, but will prevent something like "10.001", "123hello123", and so on.
Code:
int iMyInteger;
GetInput(iMyInteger);
// iMyInteger now holds a user value
To be even more sure, that the input actually worked, we can check it with the boolean value the function returns.
Code:
if(GetInput(iMyInteger))
    // Everything went fine
else
    // Everything went... wrong
As you can see you've a lot control, and it's easy to use.

I've other optimization tips for you as well.
You need to look at your headers, but also the headers and what the program actually uses of functions, objects, etc. First take a look at second line, where you're including the time header. In the way you're doing it, it's deprecated. In C++, all the old standardized libraries, have gotten "new names" if we can say that. So instead of the ".h" in the end, you put a 'c' in the start. It's not only for the time library, but also for stdlib, stdio, and so on.
Code:
#include <ctime>
#include <cstdlib>
#include <cstdio>
// ...
Now you've to look at the rest of the program too. You're using a lot of functions and objects, without including the headers for 'em. The first that felt into my eyes were std::string. You don't even includes the string library. You should. The second is exit(), which is btw not used anymore in C++. Alternatives would be std::exit(), or the good old return-statement, to do the same.

My last tip, is not something you've to change, but it is much easier to use, to you might want to think about it. It's how you're handling the different numbers, when printing the message about how many guesses you used for finding the right number. You're using if-statements... that's just fine, but with a single switch-statement, the code will be much nicer and cleaner. To "support" multiple cases, you can do as following.
Code:
case 1:
case 2:
case 3:
    // Do something, if the number was 1, 2 or 3.
    break;
When you're using exit() - or if it was me, a return-statement, you don't even need the break neither. Because when using those functions, the break-statement will never be executed anyway.

I've decided not to post the corrected code, so you've to do something by yourself. If you want me to post it, I'll post it in here, so you can take a look at it.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #3 (permalink)  
Old 07-08-2007, 05:18 PM
Xochiquetzal Xochiquetzal is offline
Newbie
 
Join Date: Jun 2007
Posts: 5
Rep Power: 0
Xochiquetzal is on a distinguished road
Default

I fixed the headers, switch-statements, returns and that. I did keep my <iostream> instead of <cstdio> and <cstdlib> after getting a Segmentation fault from trying to use a string in a printf() function...

However, after spending many hours lately trying to figure out how to use the input-validating code you provided, I've only got it to compile twice - and that was after much editing and without calling the template function. I do get how the template function is supposed to work, but I've reached the end of my debug-unknown-code-skills. I just can't get rid of my last error. I've simply decided to let it be for now, until I've learned more and can fix it.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply



Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

Similar Threads
Thread Thread Starter Forum Replies Last Post
Please Help With A C Program!! siren C and C++ 7 04-17-2007 08:45 AM
Interacting with the Mic input FlyByWire128 General Programming 2 02-23-2007 01:21 PM
Java:Tutorial - User Input John Java Tutorials 0 12-09-2006 07:25 PM
Storing a Secure Password dirkfirst PHP Forum 7 07-22-2006 10:45 PM


All times are GMT -5. The time now is 12:05 AM.

Contest Stats

John ........ 223.00000
dargueta ........ 168.00000
Xav ........ 164.00000
LogicKills ........ 20.00000
sam ........ 20.00000
gaylo565 ........ 18.00000
|pH| ........ 15.00000
WingedPanther ........ 15.00000
Johnnyboy ........ 3.00000
navghost ........ 1.00000

Contest Rules

CodeCall Goal

Goal: 100,000 Posts
Complete: 67%

Ads