argv中的字符串是否可修改?

时间:2016-01-30 14:24:52

标签: c string command-line-arguments argv

我刚写了一个小程序,用C语言读取命令行参数,没什么太难的。我也在修改它们,例如将参数的第一个字符更改为大写。

我知道你不应该修改字符串文字,因为它可能导致未定义的行为,所以只是想知道*argv[]中的字符串是否是你不应该改变的文字。

int main(int argc, char *argv[])

2 个答案:

答案 0 :(得分:26)

根据C11标准草案N1570,§5.1.2.2.1/ 2:

  

参数argcargv以及argv指向的字符串   数组应由程序修改,并保留其最后存储的数据   程序启动和程序终止之间的值。

它们是可修改的。这意味着它们不是字符串文字。

但是要小心:上面的引文只引用指针到字符串,不包括argv[argc] 1 上的强制空指针。
根据C11标准草案N1570,§5.1.2.2.1/ 2(与上述相同) 1

  

argv[argc]应为空指针

注意:

  • 关于这句话的一些事情:

      

    我知道你不应该修改字符串文字,因为它可能导致   未定义的行为[...]

    “罐”?它总是如此。未定义的行为包括预期的,好像定义明确的和意外的行为。

1 感谢@black!

答案 1 :(得分:3)

支持argv中字符串的数组是可修改的 但是你无法知道它们的尺寸。

在看到(试图)增加字符串大小的代码时,我会皱眉头。

#include <stdio.h>
#include <string.h>
// this program may behave erraticaly
int main(int argc, char **argv) {
    for (int k = 1; k < argc; k++) {
        printf("original argv[%d] is %s\n", k, argv[k]);
    }
    printf("\n");
    for (int k = 1; k < argc; k++) {
        strcat(argv[k], " foo"); // add foo to each argv string
        printf("first modification to argv[%d] is %s\n", k, argv[k]);
    }
    printf("\n");
    for (int k = argc; k > 1; k--) {
        strcat(argv[k - 1], " bar"); // add bar to each argv string
        printf("final argv[%d] is %s\n", k - 1, argv[k - 1]);
    }
    return 0;
}

在我的机器上,使用one two three参数调用该程序会产生

original argv[1] is one
original argv[2] is two
original argv[3] is three

first modification to argv[1] is one foo
first modification to argv[2] is foo foo
first modification to argv[3] is foo foo

final argv[3] is foo foo bar
final argv[2] is foo foo foo bar bar
final argv[1] is one foo foo foo bar bar bar