trouble using strcat() to concatenate command line arguments

120 Views Asked by At

I am trying to write a program for executing multiple programs from command line arguments. I start with concatenating the argv[x] strings I pass through calling the program into bigger strings that are separated by a semicolon.

I later want to execute this strings as separate child processes within a parent process.

But I am having trouble concatenating the arguments correctly.

my code:

int main(int argc, char **argv) {

    char *wp = " ";
    for(int i=1; i < argc; i++){
            // if next argument is not a semicolon and is not null
            if((strcmp(argv[i],";") != 0) && (argv[i+1] != NULL) ){ 
                // concat this argument with whitespace
                strcat(argv[i],wp);
                // concat this argument with the next                
                strcat(argv[i],argv[i+1]);       
            }
            // go on with concatenating next arguments after semicolon if any, into new string ...
            }
       }
    // test results
    printf("\n%s",argv[1]);

    // go on with executing argv as a child process..
}

I call the above program with ./program ls -l -a . \; date and the output is: ls -a .

Could someone explain why the complete series of arguments up until the semicolon is not shown? (ls -l -a .) Thank you

2

There are 2 best solutions below

0
chux - Reinstate Monica On

I start with concatenating the argv[x] strings I pass through calling the program into bigger string

Problems include

Insufficient buffer size

Code fail to properly concatenate as the destination buffer is not specified to be large enough.

// strcat(argv[i],wp);  // Bad

OP's code instead experiences undefined behavior (UB).


What should be done instead depends on OP's larger unstated goal.

1
chqrlie On

You should not write beyond the end of the strings pointed to by argv: there is no guarantee that memory can be written. You should allocate an array with local storage or from the heap and construct the string there using strcpy, strcat or even snprintf.

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

int main(int argc, char **argv) {
    size_t total = 0;
    for (int i = 1; i < argc; i++) {
        total += 1 + strlen(argv[i]);
    }
    char *str = malloc(total + 1);
    if (str == NULL) {
        perror("cannot allocate string");
        return 1;
    }
    size_t pos = 0;
    *str = '\0';
    for (int i = 1; i < argc; i++) {
        if (strcmp(argv[i], ";") && *argv[i]) {
            if (pos > 0)
                str[pos++] = ' ';
            pos += strlen(strcpy(str + pos, argv[i]));
        }
    }
    // test results
    printf("%s\n", str);

    // go on with executing argv as a child process
    //...
    
    // free memory
    free(str);
    return 0;
}