Thread: in program command console

  1. #1
    Registered User
    Join Date
    Mar 2006
    Posts
    17

    in program command console

    ok, i'm trying to make something like a command console in games.
    it takes a line of input from the user, then breaks the line down into a command and the parameters for it.
    i want to use this to do something like:
    Code:
    if (command=="dothis"){
         dothis(parameter[0],parameter[1])
    }
    here's what i have so far:

    Code:
    #include <iostream>
    #include <sstream>
    #include <math.h>
    using namespace std;
    const string cmd_create="create";
    const string cmd_exit="exit";
    
    int main(){
        bool run=1;
        string input;
        int numparameters;
        
        //in-game command line loop
        do{
        string * parameter;
        string * command;
        command = new string;
        //get input from user
        getline(cin,input);
        //display what the user entered;
        cout << input << endl;
        //turn the input into a stream
        stringstream inputstream(input);
        //take the first part of input and turn it into the command variable
        inputstream >> *command;
        // set the number of parameters based on the command
        if (*command==cmd_create){numparameters=1;}
        else {numparameters=1;}
        
        //take the rest of input and turn it into parameters
        parameter = new string[numparameters];
        for(int count=0;count<numparameters;count++){
             inputstream >> parameter[count];}
    
        //display the command the parameters to be used
        cout << "Command: " << *command << endl;
        for(int count=0;count<numparameters;count++){
             cout << "Parameter[" << count << "]: " << parameter[count] << endl;}
             
        //execute commands using parameters
        if (*command==cmd_create){
             cout << "Creating " << parameter[0] << "..." << endl;
             cout << parameter[0] << " created!" << endl;}
        if (*command==cmd_exit){
             cout << "Exiting program..." << endl;run=0;}
        delete command;
        delete []parameter;
        }while(run==1);
        return 0;
    }
    am i heading in the right direction? or can you see any bad parts to this, because everything compiles and runs fine so far.



    and on a wierd note, when i first started writing this post, i ended my sentences with semicolons...

  2. #2
    Registered User OnionKnight's Avatar
    Join Date
    Jan 2005
    Posts
    555
    Despite what your teacher might say, commenting a lot will make your code hard to read. Only use them to describe things that aren't obvious or as a summary for what a big block of code does.
    As for the code I don't see why you're making dynamically allocated strings.

  3. #3
    Registered User
    Join Date
    Mar 2006
    Posts
    17
    what teacher? heh, i'm teaching myself.
    anways, the comments are just there for now to help me keep track of things, when i get everything sorted out i'm going to take them out and just put in one or two to say what the chunk of code is doing.

    i'm basically trying to simulate the dos command console, so the user can input anything, but if they input the right things, the program does something.

    so like if the user inputs:
    add 1 2
    the program would break it down and run:
    add(1,2)

    in otherwords if the user inputs:
    command parameter1 parameter2 parameter3 (for an "infinite" number of parameters)
    and then the program takes that and runs a function
    command(parameter1,parameter2,parameter3,etc)

    so i need dynamic allocated strings, because if the user just puts
    command parameter1
    if only needs to run
    command(parameter1)
    and if they enter a command that takes 50 parameters, i need 50 parameters.

    it should save memory and also this way i don't have to manually initialize 50 parameters.

    oh and just ignore the "create" command thing, that's just an example piece i made for myself to test stuff.

  4. #4
    Registered User OnionKnight's Avatar
    Join Date
    Jan 2005
    Posts
    555
    I was thinking more about the command variable. In all it's uses it's being dereferenced so a normal string should suffice unless you have something planned for it.

  5. #5
    Registered User
    Join Date
    Mar 2006
    Posts
    17
    i forgot why i had it like that, but there was a reason. i'll remember it when i need to.

    but other than that, it looks good?

    i just wanted to make sure everything was in working order before i started making commands and things.

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    How about
    Code:
    #include <iostream>
    #include <iomanip>
    #include <string>
    #include <vector>
    #include <map>
    
    using namespace std;
    
    typedef vector<string> argv;  // command/parameters
    typedef void (*fn)(argv&);    // a function
    typedef map<string,fn> table; // a lookup table
    
    // all the functions take the same args
    void fnCreate ( argv &args ) {
      cout << "Hello from fnCreate " << args[0] << endl;
    }
    void fnEdit ( argv &args ) {
      cout << "Hello from fnEdit " << args[0] << endl;
    }
    
    int main() {
      table commands;
    
      // the lookup table of command names
      // and handler functions
      commands["create"] = fnCreate;
      commands["edit"] = fnEdit;
    
      // create a command
      argv  args1;
      args1.push_back("create");
      args1.push_back("file");
    
      // the big magic lookup :)
      // actually, test the command exists before trying to call it
      commands[args1[0]]( args1 );
    
      return 0;
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    Mar 2006
    Posts
    17

    Question

    can you(or someone) explain that code more? and what i should do with it?

    i'm still in the learning stages, and looking at that, i don't have a clue how to use it...

    i tried compiling it, but it just runs real quick and closes, and i don't know where to take in user input and how to compare it using that...

    thanks for the example though
    and thanks in advance

  8. #8
    Registered User OnionKnight's Avatar
    Join Date
    Jan 2005
    Posts
    555
    Salem is using a vector. In your code you are allocating an array of strings to hold the arguments which is then pointed to by parameter and after it's use it's being freed so it can be used again in the next iteration.
    A vector is an array that takes care of the allocation itself so you don't have to do all that so as you retrieve the arguments you can push them into a vector instead.

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > and what i should do with it?
    Wrap your user interface around it.

    It's just a demo which brings together some interesting ideas which you can learn from and adapt to your circumstances.

    > i tried compiling it, but it just runs real quick and closes
    See the my-console-closes-quickly FAQ entry

    I didn't bother with all the user input etc, because you seemed OK with it.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  10. #10
    Registered User
    Join Date
    Mar 2006
    Posts
    17
    ok here's what i've figured out so far

    i create a variable type of type vector, which is a string, called argv.
    i create a variable type of type void, then make it a pointer, which points to a function, with arguments of argv type(?, and why is the & there?).
    i create a variable type of type map, which contains a string and a pointer to a function(?), called table.

    then i create my functions.

    then i initialize my table.
    put values into my table(the command string and corresponding function).

    then initialize an argv to compare input to.
    then i use .push_back(<string>) to add a command to the argv array.
    my first command is the first position in the array, and my second command the second position and so on.

    i then compare my input with the argv, like this:
    Code:
    if (input==args1[0])  commands[args1[0]]( args1 );
    and it run my function if the input matches the command.
    it does this by comparing input to the element of the argv that i tell it to

    now here's where i'm stuck
    i need to take the input string from the user and convert it into an argv, so that each unbroken string of characters becomes an element.
    i'm thinking like this:
    input = "command argument1 argument2 argument3"
    args2[0] = "command"
    args2[1] = "argument1"
    args2[2] = "argument2"
    args2[3] = "argument3"


    here's the code i have in my head:
    Code:
    table commands;
    commands["command"]=fnCommand;
    commands["exit"]=fnExit;
    argv args1;
    args1.push_back("exit");
    args1.push_back("command");
    string input;
    argv arg2;
    bool run=1;
    do{
    getline(cin,input);
    //convert input into args2 like i explained above
    for(int count=0;count<args1.size();count++){
       if(args2[0]==args1[count]){commands[args2[0]](args2);}
       if(args2[0]==args1[0]){run=0;}}
    }while(run);
    i was trying to do it with stringstreams, but i couldn't figure it out to make it work right.
    Last edited by howzer; 03-19-2006 at 01:38 PM.

  11. #11
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > and why is the & there?).
    To pass a reference to, rather than a copy of the arguments.

    You're pretty much on the right track, except that you don't need to do this yourself.
    > if(args2[0]==args1[count]) commands[args2[0]](args2);

    If you read up on std::map, you should be able to do (with a single if()), a test to see if the command is one you recognise. If it is, then you can call any of the functions you recognise using the single line of code I posted previously.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  12. #12
    Registered User
    Join Date
    Mar 2006
    Posts
    17
    Code:
    #include <iostream>
    #include <iomanip>
    #include <string>
    #include <sstream>
    #include <vector>
    #include <map>
    
    using namespace std;
    
    typedef vector<string> argv;  // command/parameters
    typedef void (*fn)(argv&);    // a function
    typedef map<string,fn> table; // a lookup table
    
    
    // all the functions take the same args
    //declare functions here
    void fnCreate ( argv &args );
    void fnMove ( argv &args );
    void fnExit ( argv &args );
    
    int main() {
      bool run=1;
      string input;
      table commands;
      commands["create"] = fnCreate;  // the lookup table of command names
      commands["move"] = fnMove;  // and handler functions
      commands["exit"] = fnExit;
      argv  args1;//arguments vector
      do{//command line loop
      getline(cin,input);
      stringstream inputstream(input);
      do{//convert input string into argument strings
         args1.push_back("");
         inputstream >> args1.back();
       }while(inputstream);
      if (commands[args1.front()]){
      commands[args1.front()]( args1 ); //run command
      if (args1.front()=="exit"){run=0;}}
      else {cout << "No such command: " << args1.front() << endl;}
      args1.clear();
      }while(run);
    
      return 0;
    }
    i think i've got it all now. at the very least, i learned a lot today.
    Last edited by howzer; 03-19-2006 at 04:34 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Issue with program that's calling a function and has a loop
    By tigerfansince84 in forum C++ Programming
    Replies: 9
    Last Post: 11-12-2008, 01:38 PM
  2. Need help with a program, theres something in it for you
    By engstudent363 in forum C Programming
    Replies: 1
    Last Post: 02-29-2008, 01:41 PM
  3. Replies: 4
    Last Post: 02-21-2008, 10:39 AM
  4. My program, anyhelp
    By @licomb in forum C Programming
    Replies: 14
    Last Post: 08-14-2001, 10:04 PM