使用strcat()连接命令行参数时出现问题

t0ybt7op  于 2023-05-16  发布在  其他
关注(0)|答案(2)|浏览(199)

我试图写一个程序执行多个程序从命令行参数。我首先将通过调用程序传递的argv[x]字符串连接成由分号分隔的更大的字符串。
稍后我想将这些字符串作为父进程中的单独子进程来执行。
但我在正确连接参数时遇到了麻烦。
我的代码:

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..
}

我用./program ls -l -a . \; date调用上面的程序,输出是:ls -a .
有人能解释一下为什么直到分号之前的一系列参数没有显示出来吗?(ls -l -a .)谢谢

a8jjtwal

a8jjtwal1#

你不应该写在argv指向的字符串的结尾之外:不能保证存储器可以被写入。您应该使用本地存储或从堆中分配一个数组,并使用strcpystrcat甚至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;
}
fzwojiic

fzwojiic2#

我首先将通过调用程序传递的argv[x]字符串连接成更大的字符串
问题包括

缓冲区大小不足

代码无法正确串联,因为未指定足够大的目标缓冲区。

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

OP的代码反而经历了 undefined behavior(UB)。
而应该做什么取决于OP更大的未陈述的目标。

相关问题