So I'm trying to build a shell, and I've been stuck for days just trying to think about how to take in the input from the user. I need to be able to have a list of dynamically growing commands, that each has its list of dynamically growing arguments, so that I can handle situations where pipes occur, or regular commands occur with arguments, or redirections etc.

my first idea was make a struct of command types that held the char* command name, an array of arguments, and the size for the array of args. I could then make a vector of this. This idea seems pretty difficult to do though

The second idea was make a vector of vectors of char*s. so like
vector< <vector<char*> >, but this gives me errors like ISO C++ forbids items with no type. So i guess I cannot declare a vector of vectors? or am I declaring it wrong.

I want the easiest possible way to do this, because I am just stuck on it for three days straight now.

If someone could help me I would much appreciate it.

Recommended Answers

All 2 Replies

You're declaring it wrong; that'd be vector< vector<char *> >

You're declaring it wrong; that'd be vector< vector<char *> >

okay so problem with this vector of vector of chars is it prnts me garbage when i test it

I have the take input functoin here:

takeInpt(vector< vector<char*> > &cmds)
{
	char inpt[255];
	char* cmnd;
	int count=0;
	vector<char*> in;

	//ask for and get the input	
        cout << "statsh$: ";
        
        cin.getline(inpt,255); //leave plenty of room for input

	cmnd = strtok(inpt, " "); 

	//first thing should be some command
	in.push_back(cmnd);        
	
        //all the rest will either be commands or arguments
	cmnd = strtok(NULL, " "); //get next item
	
	    while(cmnd != NULL)
	    {
	        count=1; //gotten first command looking for arguments
	
	        if(strcmp(cmnd,"|") == 0)
	        {
	            piped = true;
	            cmnd = strtok(NULL, " "); //go over the pipe and get next token
	       
	            if(cmnd != NULL)
	            {
			cmds.push_back(in);
			vector<char*> pipe;
			in = pipe;
		        //fill command with relevant information
	                in.push_back(cmnd);
	            }
	            else
	            {
		        cerr << "You didn't pipe into anything" << endl;
	            }
	        }
	        else if(strcmp(cmnd,">") == 0)
	        {
	            cmnd = strtok(NULL, " "); //go over > and get next token     
	            if(cmnd != NULL)
		    {
		        redFile = cmnd; //first redirection file 
		        redType = STDOUT;
		    } 
	    	    else 
	    	    {
              	        cerr<< "Redirect to what now?? " << endl;
            	    }
                } 
	        else if (strcmp(cmnd, "<") == 0) 
	        {
            
		    cmnd = strtok (NULL, " "); //go over < and get next token

            	    if (cmnd != NULL)
	    	    {
                        redFile = cmnd;
                        redType = STDIN;
                    }   
	    	    else 
	    	    {
                        cerr<<  "Redirect what now?? " << endl;
            	    }
	        }
	
	        else //get arguments to the current command
	        {
		     in.push_back(cmnd);
	        }
	        cmnd = strtok(NULL, " ");
	}

        cmds.push_back(in);
	
        return count; //return size of input
  
}

From main i call the following:

int main()
{
   tms systemTime;
   clock_t sysTime;

   int argNums = 0;
   char* cmnd;
   vector< vector<char*> > commands;
  
   //init link list ignore for now
   lnkLst* head;
   head = new lnkLst;
   head->process = " ";
   head->sysTm = 0.0;
   head->useTm = 0.0;
   head->nxt = NULL;

   displayID();
   displayInfo();

   while(1)
   {
	
	//init just in case
	runmode = 0;   
        redFile = NULL;
	
	//take input from user 
   	argNums = takeInpt(commands);

	if( !commands.empty() )
	{
	    for(int i=0; i < commands.size(); i++)
	    {
	         //vector<char*> com = commands[i];
	         cout<< "Command" << i << " is: ";
	         for(int j=0; j < commands[i].size(); j++)
	         {
		    cout<< commands[i][j];
                 }
   }
	
   //freeList(head);
	
   return 0;

}

This prints out command0 is: command1: (garbage prints here) etc..

Why isn't it echoing back what i typed into the command line for take input?

I am missing something crucial here I think about C/c++

If you could point me in the right direction i would much appreciate. Thanks again for all of your continued help btw.

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.