Sign in to follow this  
Shewolf

How to check user input

Recommended Posts

im currently learning C++ and i am messing with some small sample programs. Here is my code
#include <iostream> // needed for I/O
#include <stdlib.h> 

using namespace std;

int PCInfo();

int main()      // Main funtion.
{
    

   PCInfo();   
  
  system("PAUSE");	// Keep window open.
  return 0;
}

int PCInfo()
    {
        string PCName;
        string Race;
        
        
        
        cout << " pick a name " << endl;
        cin >> PCName;
        cout << " pick your race. Type 'human' for Human Race or 'elven' for Elven race. " << endl;
        cin >> Race;
        cout << " Your name is " << PCName << " " << " and yor race is " << Race << " " << endl;
    }    
What I want to know is, for the user name, if they enter a number, how do i create an error for that and have it repeat the funtion PCInfo()? thanks.

Share this post


Link to post
Share on other sites
You can check for a number with the isdigit() method in the cctype standard library.

Quote:

What I want to know is, for the user name, if they enter a number, how do i create an error for that and have it repeat the funtion PCInfo()? thanks.


You should try something like this instead:

bool getPCInfo()
{
string PCName = "";
string PCRace = "";
// I/O output omitted

if (PCRace == "human" || PCRace == "elven")
return true;
else
return false;
}

int main()
{
bool finishedCharacterCreation = false;
while (!finishedCharacterCreation)
{
finishedCharacterCreation = getPCInfo();
}
}


If you want the user to select from among several well-defined types, it's probably better to use an enumeration:

enum PlayerRace
{
Human,
Elf,
Dwarf,
Gloobleshnortz
};

// ...

bool setupPCRace
{
// ...
if (isInvalidRace(PCRace))
{
return false;
}

switch (PCRace)
{
case PlayerRace.Human:
player.setHitPoints(100);
player.setManaPoints(80);
break;
case PlayerRace.Elf:
player.setHitPoints(80);
player.setManaPoints(125);
break;
// ...
}

return true;
}


In this particular case, however, it seems better to let the user pick from a menu. (1) for human, (2) for elven, that kind of thing. Then you can use a switch statement ot handle your logic:

switch (PCRace)
{
case 0: // human
// ...
case 1: // elven
// ...
};

Share this post


Link to post
Share on other sites
Well, here's one way to do it. First, after receiving an input, go through the string character at a time looking for something you don't want (a 0-9 in your case). Then if everything checks out, return a "1". Otherwise have your PCInfo() return a "0". Then in your main() just keep calling the procedure (in a loop) until it returns a 1.

Share this post


Link to post
Share on other sites
Thanks so much for all the help. That makes so much more sence. I am getting one error though. It keeps giving me 19 C:\Dev-Cpp\RaceList.cpp syntax error before `{' token

in the line

bool setupPCRace
{

if(IsInvalidRace(PCRace))
{
return false;
}

Tanks

Share this post


Link to post
Share on other sites
Quote:
Original post by Shewolf
bool setupPCRace // <-- Arr matey whaur's ye bloomin argument list?
{

if(IsInvalidRace(PCRace))
{
return false;
}


Even if you want no parameters for a function, you still need ()'s there.

Share this post


Link to post
Share on other sites
Hmm...still getting an error

#include <iostream>
#include <cstdlib>

using namespace std;

enum PCRace
{
Human,
Elf,
HalfElf,
Dwarf,
Dratch,
Fay,
Lycanthrope,
Dryad
};

bool setupPCRace()
{

if (IsInvalidRace(PCRace))
{
return false;
}

switch (PCRace)
{
case PCRace.Human:
player.SetHitPoints(15);
player.SetManaPoints(10);
player.SetDexPoints(12);
case PCRace.Elf:
player.SetHitPoints(12);
player.SetManaPoints(15);
player.SetDexPoints(10);
case PCRace.HalfElf:
player.SetHitPoints(14);
player.SetManaPoints(12);
player.SetDexPoints(11);
case PCRace.Dwarf:
player.SetHitPoints(15);
player.SetManaPoints(10);
player.SetDexPoints(15);
case PCRace.Dratch:
player.SetHitPoints(15);
player.SetManaPoints(11);
player.SetDexPoints(13);
case PCRace.Fay:
player.SetHitPoints(10);
player.SetManaPoints(20);
player.SetDexPoints(10);
case PCRace.Lycanthrope:
player.SetHitPoints(15);
player.SetManaPoints(10);
player.SetDexPoints(14);
case PCRace.Dryad:
player.SetHitPoints(12);
player.SetManaPoints(15);
player.SetDexPoints(12);
}
return true;
}

Share this post


Link to post
Share on other sites
Quote:
Original post by Shewolf
What I want to know is, for the user name, if they enter a number, how do i create an error for that and have it repeat the funtion PCInfo()? thanks.

You can error check cin.operator>>


while(true)
{
if (!(cin >> PCName))
{
//the user entered invalid input
//clear the fail bit of the input stream
cin.clear();
//clear all the junk out of the input stream
//junk could be numbers, carriage returns, spaces, tabs, etc.
cin.flush();
//output an error message
cout << "You entered an invalid name. Try again.\n";
}
else
{
//the user entered valid input
break;
}
}


Quote:

cin >> PCName;
cin >> Race;


This will also not work correctly if I enter "John Doe" for my name. PCName would be "John" and Race would be "Doe".

Share this post


Link to post
Share on other sites
Quote:
Original post by Shewolf

switch (PCRace)
{
case PCRace.Human:
player.SetHitPoints(15);
player.SetManaPoints(10);
player.SetDexPoints(12);
case PCRace.Elf:
player.SetHitPoints(12);
player.SetManaPoints(15);
player.SetDexPoints(10);

etc...
}
return true;
}

You need to use the break statement in a switch statement, or else it will keep stepping down through your code. Try putting "break;" after you call player.SetDexPoints(int) in those case statements.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this