传递包含"!!!!"的字符串时,argv的异常行为 [英] Strange behavior of argv when passing string containing "!!!!"

查看:93
本文介绍了传递包含"!!!!"的字符串时,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!!!!'

^^输出正是...

^^ The output is exactly ...

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.

相反,当您使用单引号时,外壳程序不执行 的任何替换操作,并且将字符串未经修改地传递给程序.

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

因此,您需要使用单引号来传递此字符串.如果您的用户不希望发生任何替换,则需要知道这一点.另一种方法是创建一个包装程序外壳脚本,该脚本提示用户输入要传递的字符串,然后该脚本随后将使用适当的参数来调用您的程序.

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天全站免登陆