【发布时间】:2018-07-19 02:43:45
【问题描述】:
我编写了一个小程序,它从*argv[] 获取一些输入参数并打印出来。在几乎所有用例中,我的代码都运行良好。只有当我在要作为参数传递的字符串末尾使用多个感叹号时才会出现问题...
这行得通:
./program -m "Hello, world!"
这不起作用:
./program -m "Hello, world!!!!"
^^ 如果我这样做,程序输出要么是该字符串的两倍,要么是我在 ./program 之前输入的命令。
但是,我绝对不明白:以下,奇怪的是,确实有效:
./program -m 'Hello, world!!!!'
^^ 输出正好是……
Hello, world!!!!
...随心所欲。
所以,我的问题是:
- 为什么在字符串中使用多个感叹号时会出现这种奇怪的行为?
- 据我所知,在 C 语言中,
""用于字符串,''用于单个字符。那么为什么我在使用''时会得到想要的结果,但在使用""时却没有(在我的理解中)? - 我的代码是否有错误,或者我需要更改什么才能输入任何字符串(无论是否使用、使用什么以及使用多少标点符号)并准确打印该字符串?
我的代码的相关部分:
// this is a simplified example that, in essence, does the same
// as my (significantly longer) code
int main(int argc, char* argv[]) {
char *msg = (char *)calloc(1024, sizeof(char));
printf("%s", strcat(msg, argv[2])); // argv[1] is "-m"
free(msg);
}
我已经尝试先将argv[2] 的内容复制到char* 缓冲区中,然后将'\0' 附加到其中,这并没有改变任何内容。
【问题讨论】:
-
为什么是
printf("%s", strcat(msg, argv[2]))而不是printf("%s", argv[2]))?? -
空格,你需要转义它。另外,
calloc()没有多大意义。只是char msg[1024]非常好。当您使用单个 qoutes 时,字符串按原样传递。这与argv或c 编程语言无关,而是与shell 相关 -
@Michael Walz:因为我在 msg 中创建了一个更长的字符串。将 argv 的内容附加到它只是我完整代码中许多步骤中的第一步。很抱歉没有早点澄清。
-
感叹号是你的shell的一个特殊字符(可能是
bash)。如果它没有放在单引号中,shell 会解释!!并将其替换为其他内容(历史上的前一个命令)。您的程序可以正常运行,它会在命令行中打印从 shell 接收到的内容。 -
@ci7i2en4: 1) 语法错误是在扩展过程中创建的 bash 语法错误,在这种情况下您的程序甚至没有启动,2) 您的程序应该负责验证输入值,但您不能“撤消” bash 完成的扩展。您应该做的事情是:检查
argc是否具有有效长度并检查参数是否有意义,然后可能会显示带有使用信息的错误消息。