【问题标题】:Are the strings in argv modifiable?argv 中的字符串可以修改吗?
【发布时间】:2016-05-08 06:35:10
【问题描述】:

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

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

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

【问题讨论】:

  • 这不是文字。你可以改变它。
  • @user007 不是重复的。这个问题没有提到任何关于字符串文字的内容。
  • 如果你没有在你的程序中写一个字符串,并且用引号把它包起来,它就不是一个字符串文字。
  • @JonathonReinhart 哦,哇,我不知道,谢谢!

标签: c string command-line-arguments argv


【解决方案1】:

来自 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!

【讨论】:

  • 感谢您的回答,我知道它总是会导致未定义的行为我想我应该更明确地提出我的问题,我现在会更改它。
  • 这是否意味着指针本身可以被修改? IE。可以吗:argv[0] = NULL
  • @Jongware 据我所知,第一个引号直接与以下内容相矛盾:“[...] argv 数组指向的字符串应可由程序修改 [... ]," 因此,除非参数是从 ROM复制,否则它们不能存储在只读存储器中。还是“字符串”指的是指针本身? IMO,它没有。
  • 我很确定argv[argc] == NULL-thing 是环境的保证,而不是禁止程序修改。
  • @2501 我问过question,只是为了让你知道。
【解决方案2】:

支持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 参数调用该程序会产生

原始 argv[1] 是一个 原来的 argv[2] 是两个 原来的 argv[3] 是三 对 argv[1] 的第一次修改是一个 foo 对 argv[2] 的第一个修改是 foo foo 对 argv[3] 的第一个修改是 foo foo 最后的 argv[3] 是 foo foo bar 最后的 argv[2] 是 foo foo foo bar bar final argv[1] 是一个 foo foo foo bar bar bar

【讨论】:

  • 谢谢!是的,我并没有真正增加或减少大小,只是将字符更改为大写或小写。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-06
  • 2015-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多