Thread: Shell Assignment — Help with strtok

  1. #1
    Registered User
    Join Date
    Jan 2012
    Posts
    14

    Question Shell Assignment — Help with strtok

    Hey guys. My college assignment is to write my own shell in C. The shell prints the prompt with the current directory and waits for user input. Then it should break the user input into tokens, with spaces as the separators. It manually executes the operations if the user calls "exit" or "cd" to change the working directory. Otherwise, it should fork and run execvp, passing it the string of the first token typed and also the array (argsArray here) of the rest of the arguments.

    My problem is that it seems to always leave the LAST token of user input with a ton of blank characters on the end of it. For example, if I type "cd /users/MyUser" ...... then it recognizes the first token as "cd" but it stores the secong argument as "/users/MyUser " ...... in other words, it tacks on a bunch of spaces, and so when I compare the strings or when I pass the strings as arguments, the computer does not recognize them.

    Here's my code. I was wondering if anyone could help out. There are a bunch of commented lines that you can more or less ignore, those are notes for my teacher if I pass it in as-is. Thanks.

    Code:
    #include <stdio.h>
    #include <unistd.h>
    #include <errno.h>
    #include <stdlib.h>
    #include <string.h>
    #define LINELENGTH 100
    #define MAX_ARGS 100
    
    int countArgs(char* bufferTest) {
        char *delimiters = " \t\n";
        int counter = 0;
        char *first = strtok(bufferTest, delimiters);
        counter++;
        //printf("Token %d is %s \n", counter++, first);
        char *next1;
        while(next1 = strtok(NULL, delimiters)) {
            counter++;
            //printf("Token %d is %s \n", counter++, next1);
        }
        return counter;
    }
    
    int main(int argc, char **argv)
    {
        char buffer[100];
        char bufferCopy[100];
        char cwd[100];
        char exit1[100];
       // char *args[MAX_ARGS];
        
        while(1)
        {
            if(getcwd(cwd, sizeof(cwd)) != NULL)
                printf("bcshell %s:", cwd);
            else {perror("Error finding current directory.\n"); return 0;}
            // print out the prompt
            printf("My Shell >> ");
            // get the user input
            fgets(buffer, 100, stdin);
            
            printf("%s\n", buffer);
            // this is the child
            strcpy(bufferCopy, buffer);
            int numArgs = countArgs(bufferCopy); // create countArgs method
            printf("Number of args is : %d \n", numArgs);
            
            
            char* argsArray[MAX_ARGS];
            int counter = 0;
            char* next;
            char* delimiters = " \t\n";
            next = strtok(buffer, delimiters);
            while(next != NULL)
            {
                argsArray[counter] = malloc(sizeof(strlen(next)));
                strcpy(argsArray[counter], next);
                next = strtok(NULL, " "); // This is adding extra null space on string.
                printf("Element %d is: %s .", counter, argsArray[counter]); // this is problem I can't solve.
                counter++;
            }
    
            // if exit is called
            printf("about to exit check..\n");
            printf("%s\n", argsArray[0]);
            if(strncasecmp(argsArray[0], "exit", 4) == 0) { // First 4 of argsArray[0] work..
                printf("Exiting!!!\n"); // but like I said.. it's adding lots of null chars
                exit(0); // to the end of whatever my last token in the input is.
                // I imagine this is a simple fix that would fix my whole program...
            }
    
            // if cd is called
             if(strcasecmp(argsArray[0], "cd") == 0) {
             printf("String is %s", argsArray[1]);
             char* directory = argsArray[1];
             int ret;
             ret = chdir(directory);
             if(ret != 0) { // error check.
             printf("Error changing directory.\n");
             exit(4);
             } 
             //  printf("CD is... %s", directory);
             } 
            
            // time to fork
            int pid = fork();
            if(pid!=0)
            {
                wait(NULL);
                //return 0;
            }
            else
            {
                execvp(argsArray[0], argsArray);
                printf("If this is printed, execvp failed.\n");
            }
        }
        exit(0);
    }

  2. #2
    Registered User
    Join Date
    Mar 2011
    Posts
    546
    argsArray[counter] = malloc(sizeof(strlen(next)));

    this is the same as malloc(4). the sizeof returns an unsigned int (or maybe a long). if you want to make room for the string, you need to malloc(strlen(next)+1);
    the +1 is room for the terminating '\0'

    so you are printing junk from whatever follows your malloc of 4 bytes

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help using strtok
    By HIT_Braga in forum C Programming
    Replies: 5
    Last Post: 03-30-2010, 06:28 AM
  2. Replies: 3
    Last Post: 04-26-2009, 08:54 AM
  3. trying to use strtok
    By gwmexod in forum C Programming
    Replies: 3
    Last Post: 06-08-2006, 03:04 AM
  4. strtok
    By Unregistered in forum C Programming
    Replies: 1
    Last Post: 05-02-2002, 01:34 AM
  5. strtok
    By ktntech in forum C Programming
    Replies: 5
    Last Post: 01-13-2002, 09:47 AM

Tags for this Thread