How can I get a numerical value from a string? I am using the command "getline" to store a string. I want the user to be able to enter "assign 8 strength", right now they have to type "assign strength" over and over until they run out of points. Is it possible to do this?

Recommended Answers

All 8 Replies

Yes, but you need to make sure to standardize your input format and institute some good error checking otherwise your user could really wreak some havoc with the application.

How are you currently recognizing the "assign strength" command? If you're just using simple string comparison, you'll have to make some major changes.

I'm just comparing strings right now. And I don't always use getline() if that is what you mean by standarizing my input. I use plain old std::cin sometimes as well.

Not exactly what i meant. The way you read input is somewhat situation-dependent but you should be as consistent as possible.

What I meant was make sure the user understands that the required input format for a command is verb value object and that you reject any other format or arrangement.

I think what I would do is create a stringstream from the input string. Then, send the stringstream to a function called something like "getAction" which would extract the verb and return an enumerated value representing the command, then the function that reacts to that action would get the string and extract the remaining values.

I puzzled through your idea for a bit and here is what I came up with. This is just a small seperate program I used to test stringstream and how I was dealing with strings. Tell me what you think...and thanks :D

#include <iostream>
#include <string>
#include <sstream>

int main()
{
    std::string command("");
    std::string substring1;
    std::string substring2;
    int amount;
    int iterator;
    
    std::cout << ">";
    
    std::getline(std::cin,command);
    
    system("CLS");
    
    std::cout << "Original String: " << command
              << "\n"
              << "\n";
              
    iterator = command.find( " " );
    
    substring1 = command.substr( 0, (iterator));
    
    if(substring1 == "assign")
    {
                 command.erase( 0, (iterator+1));
    }
    
    
    
    iterator = command.find( " " );
    
    substring2 = command.substr(iterator+1);
    
    if(substring2 == "strength")
    {
                  command.erase(iterator);
    }
    
   
              
    std::stringstream(command) >> amount;
    
    std::cout << "Verb: " << substring1
              << "\nAmount: " << amount
              << "\nObject: " << substring2
              << "\n\n";
              
    
    system("PAUSE");
}

Wait let me get this straight, you have a command, something like this : "assign 8 strength . And this should assign strength to 8. So in general is the format going to be like so : command number attribute ?

I actually meant something more like this:

#include <iostream>
#include <sstream>
#include <cstdio>
#include <string>
#include <exception>

using namespace std;

//declare the Action enumeration
enum Action { error = -2, quit = -1, assign = 0, walk, give, talk };

//function prototypes
Action getAction(stringstream &);
void doAssign(stringstream &);

int main() {
  do {
    string userCommand;           //input string for user command
    getline(cin, userCommand);
    stringstream commandStream(userCommand);  //create the stringstream
    Action userAction = getAction(commandStream); //extract the action from the stringstream
    if (userAction == Action::quit) {         //see if the user wants to quit
      break;
    } else {
      switch (userAction) {                   //if user isn't quitting, react to the action
        case Action::assign:                  //user wants to perform an assignment
          //call the assignment function
          doAssign(commandStream);            //perform the assignment
          break;
        case Action::walk:                    //react to other commands
          /*... */
        default:
          //handle unknown commands and/or errors
      } //end switch
    }
  } while (true);
return 0;
}

Action getAction(stringstream &commandStream) {
  string commandAction;                 //a variable to hold the extracted action
  userCommand >> commandAction;         //extract the action
  if (commandAction = "assign")         //determine the requested action
    return Action::assign;
  else if (commandAction == "walk")
    return Action::walk;
  /* etc. */
  else
    return Action::error;               //or, if invalid, return an input error
}

void doAssign(stringstream &commandStream) {
  int assignValue = 0;
  string assignLocation;
  commandStream >> assignValue >> assignLocation;
  /* remaining assign actions. */
}

Notice how I'm passing around the stringstream object called "commandStream" extracting portions of it as needed?

@FBody thats a feasible solution, but the problem I see that is that the when adding new actions/commands, the code increases a lot. I would advice to apply the command pattern for this situation, or possible thevisitor pattern

Afraid I'm not familiar with those...

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.