Reputation: 31
I am trying to read valid a user input from command prompt:
for example, valid user input is in following format:
getData <>
<> - any string type value
on Command Prompt:
e.g getData name => Correct (only one parameter entered after getData as expected) e.g getData name ID => InCorrect (more than one parameter entered after getData) e.g getData => InCorrect (due to no parameter entered after getData)
How do I check for number of parameters? my code logic is as follow:
string cmd_input;
getline(cin, cmd_input)
stringstream ss(cmd_input);
string input;
string parameter;
ss >> input; //getData
ss >> parameter; //name
How do I go about valid/invalid checking? I don't want to run it through loop till EOF stream and count the number of parameter. I read up on peek() and not sure how it fits here. Also, I don't want to use vectors to store parameter.
Thanks!
Upvotes: 1
Views: 13222
Reputation: 42085
With the constraint of not using loops and not even std::vector
, it could look the following way:
std::string line, command, arg1, arg2, arg3;
if (std::getline(std::cin, line)) {
std::istringstream is(line);
if (is >> command) {
std::string word;
if (is >> arg1) {
...
if (is >> arg2) {
...
if (is >> arg3) {
...
}
}
}
} // end of is >> command
}
Yet if you change your mind and decide to use std::vector
, it could look like this:
std::string line, command;
std::vector<std::string> arguments;
if (std::getline(std::cin, line)) {
std::istringstream is(line);
if (is >> command) {
std::string word;
while (is >> word)
arguments.push_back(word);
}
}
Upvotes: 1
Reputation: 153792
Here is a simple test program reading command
s. If the command
is getData
one argument is extracted and, if this is successful, any trailing whitespace is skipped. At this point the stream parsing the line is expected to have reached its end, i.e., eof()
needs to be set:
#include <iostream>
#include <sstream>
#include <string>
int main()
{
for (std::string line; std::getline(std::cin, line); ) {
std::istringstream in(line);
std::string command, name;
if (in >> command) {
if (command == "getData" && in >> name && (in >> std::ws).eof()) {
std::cout << "getData: read one argument: '" << name << '\n';
}
else {
std::cout << "wrong format on line '" << line << "'\n";
}
}
}
}
Upvotes: 0
Reputation: 9648
ss >> input;
if( ss.eof() )
//no parameter code
else
{
ss >> param;
if( !ss.eof() )
// too many param code
else
// good input
}
Upvotes: 0
Reputation: 70372
You can check the state of the stream itself after you retrieve input. If the retrieval succeeded, it will be true
. You want it to return true
after two retrievals, but be false
on the third.
if (!(ss >> input1) || input1 != "getData") { //... error : unexpected cmd
}
if (!(ss >> input2)) { //... error: no param
}
if (ss >> input3) { //... error: too many params
}
//... okay
Upvotes: 1