传递包含“!!!!!!"的字符串时 argv 的奇怪行为; [英] Strange behavior of argv when passing string containing "!!!!"

查看:26
本文介绍了传递包含“!!!!!!"的字符串时 argv 的奇怪行为;的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写了一个小程序,它从 *argv[] 获取一些输入参数并打印它们.在几乎所有用例中,我的代码都运行良好.仅当我在要作为参数传递的字符串末尾使用多个感叹号时才会出现问题...

I have written a small program that takes some input parameters from *argv[] and prints them. In almost all use cases my code works perfectly fine. A problem only arises when I use more than one exclamation mark at the end of the string I want to pass as an argument ...

这有效:

./program -m "Hello, world!"

这不起作用:

./program -m "Hello, world!!!!"

^^ 如果我这样做,程序输出要么是那个字符串的两倍,要么是我在 ./program 之前输入的命令.

^^ If I do this, the program output is either twice that string, or the command I entered previous to ./program.

然而,我绝对不明白的是:奇怪的是,以下内容确实有效:

However, what I absolutely don't understand: The following, oddly enough, DOES work:

./program -m 'Hello, world!!!!'

^^ 输出正是...

Hello, world!!!!

... 随心所欲.

所以,我的问题是:

  • 为什么在字符串中使用多个感叹号时会出现这种奇怪的行为?
  • 据我所知,在 C 中,您将 "" 用于字符串,将 '' 用于单个字符.那么为什么我在使用 '' 时得到了想要的结果,而在使用 "" 时却没有得到想要的结果(据我所知)?
  • 我的代码中是否有错误,或者我需要更改什么才能输入任何字符串(无论使用了是否、使用什么以及使用了多少标点符号)并准确打印该字符串?
  • Why does this strange behavior occur when using multiple exclamation marks in a string?
  • As far as I know, in C you use "" for strings and '' for single chars. So why do I get the desired result when using '', but not when using "" as I should (in my understanding)?
  • Is there a mistake in my code or what do I need to change to be able to enter any string (no matter if, what, and how many punctuation marks are used) and get exactly that string printed?

我的代码的相关部分:

// 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',这没有改变任何东西.

I already tried copying the content of argv[2] into a char* buffer first and appending a '\0' to it, which didn't change anything.

推荐答案

这与您的代码无关,而与启动它的 shell 相关.

This is not related to your code but to the shell that starts it.

在大多数 shell 中,!! 是最后运行的命令的简写.当您使用双引号时,shell 允许 历史扩展(以及变量替换等)在字符串中,因此当您将 !! 放在双引号字符串中时,它会替换上次运行的命令.

In most shells, !! is shorthand for the last command that was run. When you use double quotes, the shell allows for history expansion (along with variable substitution, etc.) within the string, so when you put !! inside of a double-quoted string it substitutes the last command run.

这对您的程序意味着这一切发生在之前您的程序被执行,因此除了检查传入的字符串是否有效之外,程序无能为力.

What this means for your program is that all this happens before your program is executed, so there's not much the program can do except check if the string that is passed in is valid.

相反,当您使用单引号时,shell 不会进行任何替换,并且字符串会未经修改地传递给程序.

In contrast, when you use single quotes the shell does not do any substitutions and the string is passed to the program unmodified.

所以你需要使用单引号来传递这个字符串.如果您的用户不希望发生任何替换,则他们需要知道这一点.另一种方法是创建一个包装 shell 脚本,提示用户输入字符串,然后脚本随后会使用正确的参数调用您的程序.

So you need to use single quotes to pass this string. Your users would need to know this if they don't want any substitution to happen. The alternative is to create a wrapper shell script that prompts the user for the string to pass in, then the script would subsequently call your program with the proper arguments.

这篇关于传递包含“!!!!!!"的字符串时 argv 的奇怪行为;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆