0

In this code snippet here:

printf("shell> ");
fgets(input, MAX_INPUT_SIZE, stdin);

//tokenize input string, put each token into an array
char *space;
space = strtok(input, " ");
tokens[0] = space;

int i = 1;
while (space != NULL) {
  space = strtok(NULL, " ");
  tokens[i] = space;
  ++i;
}

//copy tokens after first one into string
strcpy((char*)cmdargs, ("%s ",tokens[1]));
for (i = 2; tokens[i] != NULL; i++) {
  strcat((char*)cmdargs, ("%s ", tokens[i]));
}

printf((char*)cmdargs);

With the input: echo hello world and stuff, the program prints:

helloworldandstuff

It seems to me that the line strcat((char*)cmdargs, ("%s ", tokens[i])); should concatenate the string at tokens[i] with a space following it. Does strcat not work with string formatting? Any other ideas what might be going on?

IrateIrish
  • 219
  • 2
  • 6
  • 12
  • Yes it compiles as is here just fine. One warning about the `printf((char*)cmdargs);` statement, but that's it. And that statement is only there for debugging purposes. – IrateIrish Sep 15 '13 at 07:03
  • it Does compile because of comma operator, while simply `"%s ", tokens[i]` is not valid as what you think – Grijesh Chauhan Sep 15 '13 at 07:07
  • 1
    read: [What is the proper use of the comma operator?](http://stackoverflow.com/questions/17902992/what-is-the-proper-use-of-the-comma-operator?lq=1) – Grijesh Chauhan Sep 15 '13 at 07:21

2 Answers2

4

strcat does not support formatting strings, it just does concatenation. Moreover, your use of the extra pair of parenthesis cause the C compiler to parse this as a comma operator, and not as arguments passed to the function.

That is, strcat((char*)cmdargs, ("%s ", tokens[i])); will result in a call strcat((char*)cmdargs, tokens[i]); as the comma operator invoke side-effect of all expression, but return the last value.

If you want to use strcat, you should write:

strcat((char*)cmdargs, " ");
strcat((char*)cmdargs, tokens[i]);

The same thing apply to the strcpy function call too.

Sylvain Defresne
  • 42,429
  • 12
  • 75
  • 85
2

Write your own version of a formatting string-concatentating function, if that's what you want:

(untested)

int strcatf(char *buffer, const char *fmt, ...) {
    int retval = 0;
    char message[4096];
    va_list va;
    va_start(va, fmt);
    retval = vsnprintf(message, sizeof(message), fmt, va);
    va_end(va);
    strcat(buffer, message);
    return retval;
}


...
strcatf((char*)cmdargs, "%s ", tokens[i]);
...
trojanfoe
  • 120,358
  • 21
  • 212
  • 242