Search code examples
carraysloopsstrcmp

checking values of array using strcmp and nested loop


I have reached the final part of the program and I am facing some issues once again.


Issue #1: When I print the separated string parts of the array in the while loop of the tokenizing, the values are ok. BUT, when I print the puts(tokenArray[1]),it results in only one letter of the command been shown, e.g: Input: "qwe rty" | Printout in while loop: qwe rty | Printout using puts(tokenArray[1]) outside the loop: "e" (yes, just the letter).


Issue #2: I noticed this while debugging. After I enter a random input and then enter "history", the tokenArray has first position filled with "history", and the next position filled with "tory". For that, I cannot use the nested loop and the strcmp as you can see below, in order to check if the first part is "history" and if so, check the second part. If the second part is empty, to just show the history of commands, or if it "1"/"2" etc (when the user has entered "history 1", to execute the first command in history.

This is my progress so far:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main (int argc, char *argv[])
{
    int i=0; int j=0; int k=0;
    char inputString[100];
    char *result=NULL;
    //char *result2=NULL;
    char delims[] = " ";
    char historyArray[100][100] = {0};
    char historyKey[] = "history";
    char *tokenArray[100] = {0} ;
    //char exitString[] = "exit";

    do
    {
        printf("hshell>");
        gets(inputString);
        strcpy (historyArray[k], inputString);
        k++;

        // Break the string into parts
        result = strtok(inputString, delims);


        while (result!=NULL)
        {
            //result2 = result;
            tokenArray[j] = result;
            //puts(result);
            result= strtok(NULL, delims);
            //puts(tokenArray[j]);
            j++;
        }
        //j = 0;
        puts(tokenArray[1]);
        if (strcmp(tokenArray[0],historyKey) == 0)
        {
            if (strcmp(tokenArray[1], " " ) == 0)
            {
                for (i=0; i<k; i++)
                {
                    printf("%d. %s \n",i+1,historyArray[i]);
                }
            }
        }
        else if (strcmp ("exit",inputString) != 0)
        {
            printf("\nCommand not found \n");
        }

    } while (strcmp ("exit", inputString) != 0);
    return 0;
}

Solution

  • Several things immediately apparent.

    1. You're never resetting the value of j from one command line to the next.
    2. strtok() is not going to tack an single-space string into your input tokens just because you enter something like "command ". It will strip the delims, so your logic is flawed with this idea. The input tokens for "command " will be a single token, for "command one " it will be "command", and "one" only. You're apparently thinking it will give you a single-space string from what you're doing with strcmp(tokenArray[1], " " ).
    3. Major, but not related your immediate problem, eventually you will overrun your stack when k becomes large enough (100 commands to be precise)
    4. Kudos to @unwind, you need to throw out the newline fetched with fgets(), which I did when testing this. Prolly shoulda mentioned that.

    Fix the first one, rethink the second, and consider an alternate structure for holding history for the third. Finally, I tested this with fgets(inputString, 100, stdin); and it does work, so no idea what is wrong on your end there.