Reading unser input & deciding course of action.

G

Gemma Fletcher

Hi all :)

I'm implementing a menu system for my assignment.

User inputs command & an if/else switch statement executes the command.

I'm just not quite sure the best way to take user input.

For eg:
L <vehicleId>
or
A <vehicleId> <Type>

So the user inputing L 123 is asking to list the vehicle who's Id is 123. Or
A 123 Ship, is asking to add a vehicle with an id of 123 and type ship.

However since all the menu commands are a mixture of just the letter (H for
help) or a command with 1 or 2 pararmeters, I can't really declare 3 input
variables and go: cin >> letter >> Id >> type, as when i run the program I
have to enter something for each variable field.

I thought maybe instead i would read in a string and then search the string
for the variables instead. However I'm not quite sure how to go about it.

I though maybe using the string class I would use the find() method, however
I'm not sure how to tell the program that once it finds (for example) the
start of a number, to read the rest of the number and save it in a temp
variable to be passed to my vehicleId variable.

Any suggestions would be appreciated,

hopefully I'm somewhat coherent - coding for hours makes my brain mushy ;)

Thanks,
Gemma
 
H

Howard Gardner

Gemma said:
I though maybe using the string class I would use the find() method, however
I'm not sure how to tell the program that once it finds (for example) the
start of a number, to read the rest of the number and save it in a temp
variable to be passed to my vehicleId variable.

Look for the spaces that separate (delimit) the input values (tokens).

Look for:
(0+)(token)(1+)(token)(1+)(token)(0+)(eol)

where:

0+ is 0 or more whitespace characters

1+ is 1 or more whitespace characters

token is a sequence of non-whitespace characters

eol is end of line

looking for the leading 0+ and the trailing 0+ is optional.

You can worry about what the tokens represent after you get them all.
 
M

Marcus Kwok

Gemma Fletcher said:
For eg:
L <vehicleId>
or
A <vehicleId> <Type>

So the user inputing L 123 is asking to list the vehicle who's Id is 123. Or
A 123 Ship, is asking to add a vehicle with an id of 123 and type ship.

However since all the menu commands are a mixture of just the letter (H for
help) or a command with 1 or 2 pararmeters, I can't really declare 3 input
variables and go: cin >> letter >> Id >> type, as when i run the program I
have to enter something for each variable field.

I thought maybe instead i would read in a string and then search the string
for the variables instead. However I'm not quite sure how to go about it.

You can use std::getline() (found in said:
I though maybe using the string class I would use the find() method, however
I'm not sure how to tell the program that once it finds (for example) the
start of a number, to read the rest of the number and save it in a temp
variable to be passed to my vehicleId variable.

If you know where the number starts and ends, you can use string's
substr() function to get a substring. Then, you can convert this
substring into an actual number.

To convert a string to a number, see
http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.2

and the FAQ following it too.
 
G

Gemma Fletcher

*sigh* I thought I was so clever....I've now been shot down terribly by my
evil assignment.

On to business - I hashed together the start of my main menu, using the
previous idea's and alot of google stuff.

Now I thought it was working <never trust an error free compile> however
have realised that converting my string to an integer is giving me the wrong
integer.

I'm assuming that is because of how I've read, tokenised and converted the
integer.

So if anyone has a quick minute to check out my code below and perhaps
suggest a less convuluted method, or point out an error - I would be very
grateful.

Just a note - the code below is only the snippet for the main menu - so it's
not going to compile. If the working code is wanted just let me know and
I'll post it.

/*Main Menu
Assumptions : Either 1, 2 or 3 paramaters will be used only. First
parameter will always be a char, 2nd always an int, 3rd always a string
*/
string buf;
string param1, temp, param3;
int param2;
string answer;

do{
cout << "Welcome to my Transport Database. \n";
cout << "Please enter a command (For help - type 'H'): ";
cin >> answer;

stringstream ss(answer); //Insert string into stream
vector<string> tokens; //Create vector to hold words
vector<string>::iterator strIter; //Creates an iterator for the
vector

while (ss >> buf)
tokens.push_back(buf); //When hits whitespace, put word into vector
for (strIter = tokens.begin(); strIter != tokens.end(); strIter++)
if (int (tokens.size()) == 1) { //If 1 paramater assign to
param1
param1 = tokens.at(0);
}

else if (int (tokens.size()) == 2) { //If 2 paramaters assign to
param1 & 2
param1 = tokens.at(0);
temp = tokens.at(1);
const char *ch = temp.c_str(); //Convert string to c-style
string
param2 = atoi(ch); //Convert c_string to int
}
else if (int (tokens.size()) == 3) { //If 3 paramaters assign to
param1, 2 &3
param1 = tokens.at(0);
temp = tokens.at(1);
const char *ch = temp.c_str();
param2 = atoi(ch);
param3 = tokens.at(2);
}

if (param1 == "H")
getHelp();
if (param1 == "A")
car->addById(param2); //Add new Vehicle with the given
parameter as it's Id
}while(param1 != "Q");


Gemma Fletcher said:
Thanks guys!!

You were both very helpful :)
 
M

Marcus Kwok

Please do not top-post.
http://en.wikipedia.org/wiki/Top-posting

Gemma Fletcher said:
Now I thought it was working <never trust an error free compile> however
have realised that converting my string to an integer is giving me the wrong
integer.

I'm assuming that is because of how I've read, tokenised and converted the
integer.

If you have errors, then it would be helpful to provide your input, your
expected output, and the actual output.
So if anyone has a quick minute to check out my code below and perhaps
suggest a less convuluted method, or point out an error - I would be very
grateful.

Just a note - the code below is only the snippet for the main menu - so it's
not going to compile. If the working code is wanted just let me know and
I'll post it.

Please follow the guidelines given at:
http://www.parashift.com/c++-faq-lite/how-to-post.html#faq-5.8
/*Main Menu
Assumptions : Either 1, 2 or 3 paramaters will be used only. First
parameter will always be a char, 2nd always an int, 3rd always a string
*/
string buf;
string param1, temp, param3;
int param2;
string answer;

do{
cout << "Welcome to my Transport Database. \n";
cout << "Please enter a command (For help - type 'H'): ";
cin >> answer;

stringstream ss(answer); //Insert string into stream
vector<string> tokens; //Create vector to hold words
vector<string>::iterator strIter; //Creates an iterator for the vector

while (ss >> buf)
tokens.push_back(buf); //When hits whitespace, put word into vector

There is no curly-brace '{' here, so the tokens.push_back(buf) is the
only statement that is executed in the while loop. Your indentation
below is therefore misleading.
for (strIter = tokens.begin(); strIter != tokens.end(); strIter++)

I do not see a need for this 'for' loop. For example, if tokens.size()
is 3 then you unnecessarily read in the parameters three times.
 
M

Marcus Kwok

Gemma Fletcher said:
Sorry - Many apoligies.
Erm...shall I repost properly? Or just leave it since the damage is done?

No need to repost the previous message, but if could post another
message following the guidelines at:

then you will be more likely to receive more useful responses. In other
words, try to simplify your code to the smallest complete example that
demonstrates your problem. Often, in the process of doing this, you may
be able to figure out the problem on your own.
 
G

Gemma Fletcher

Sorry - Many apoligies.
No need to repost the previous message, but if could post another
message following the guidelines at:


then you will be more likely to receive more useful responses. In other
words, try to simplify your code to the smallest complete example that
demonstrates your problem. Often, in the process of doing this, you may
be able to figure out the problem on your own.

Thanks for the tip. I'll definatley be more aware with my posts next time.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top