命令行参数
本节阅读量:为什么需要命令行参数?
编译并链接程序后,输出结果是一个可执行文件。当程序运行时,会从名为main()的函数开头开始执行。到目前为止,我们都是这样声明main:
|
|
请注意,这个版本的main()不带参数。然而,许多程序需要某种输入才能使用。例如,假设您正在编写一个名为Thumbnail的程序,该程序读取图像文件,然后生成缩略图(图像的较小版本)。程序如何知道要处理哪张图片?用户必须有某种方法来告诉程序要打开哪个文件。为此,可以采用以下方法:
|
|
然而,这种方法存在一个潜在问题。每次运行程序时,程序都会等待用户输入。如果您只是从命令行手动运行一次,这可能不是问题。但在其他情况下,例如想让程序处理许多文件,或者让另一个程序启动它,这种方式就会带来麻烦。
让我们进一步研究这些情况。
考虑您希望为给定目录中的所有图像文件创建缩略图的情况。您会怎么做?只要目录中有图像,就可以多次运行该程序,并手动输入每个文件名。然而,如果有数百张图像,这可能要输入一整天!更好的解决方案是编写一个程序,循环遍历目录中的每个文件名,并为每个文件调用一次Thumbnail。
现在考虑另一种情况:您正在运行一个网站,并希望每次用户将图像上传到网站时,网站都能创建一个缩略图。上述创建缩略图的程序无法从用户请求中直接获取输入图片,因此在这种情况下,上传程序如何传入文件名?更好的解决方案是让您的web服务器在上传后自动调用生成缩略图的程序。
在这两种情况下,我们都需要一种方法,让外部程序在启动缩略图程序时把文件名作为输入传入,而不是让缩略图程序启动后再等待用户输入文件名。
命令行参数是可选的字符串参数,会在程序启动时由操作系统传递给程序。然后,程序可以将它们用作输入(或忽略它们)。就像函数参数是函数的输入一样,命令行参数也为程序提供了一种接收输入的方式。
传递命令行参数
在命令行中,可以直接通过程序名来执行程序。例如,要运行Windows机器当前目录中的可执行文件“WordCount”,可以输入:
|
|
在基于Unix的操作系统上,等效命令是:
|
|
为了将命令行参数传递给WordCount,我们只需在可执行文件名后列出命令行参数:
|
|
现在,当执行WordCount时,Myfile.txt将作为命令行参数提供。程序可以有多个命令行参数,由空格分隔:
|
|
如果从IDE运行程序,也可以输入命令行参数。
在Microsoft Visual Studio中,在解决方案资源管理器中右键单击项目,然后选择属性。打开“配置属性”页面,然后选择“调试”。在右侧窗格中,有一行名为“命令参数”。您可以在那里输入命令行参数进行测试,当您运行程序时,它们将自动传递给您的程序。
使用命令行参数
现在您已经知道如何为程序提供命令行参数,下一步就是在C++程序中访问它们。为此,我们使用一种与之前不同的main()形式。这种新形式的main()接受两个参数(按照约定命名为argc和argv),如下所示:
|
|
您有时还会看到它被编写为:
|
|
尽管两种写法是等价的,但我们更喜欢第一种表示方式,因为它在直觉上更容易理解。
argc是一个整数参数,表示传递给程序的参数数量(argc=参数个数)。argc至少为1,因为第一个参数始终是程序本身的名称。用户提供的每个命令行参数都会让argc增加1。
argv是存储实际参数值的位置(argv=参数值)。尽管argv的声明看起来有些吓人,但它实际上只是一个C风格的字符指针数组(每个指针都指向一个C风格字符串)。该数组的长度为argc。
让我们编写一个名为“MyArgs”的短小程序来打印所有命令行参数的值:
|
|
现在,当我们使用命令行参数“Myfile.txt”和“100”调用该程序(MyArgs)时,输出如下:
|
|
参数0是当前正在运行的程序的路径和名称。在本例中,参数1和2是我们传入的两个命令行参数。
请注意,我们不能使用基于范围的for循环来迭代argv,因为基于范围的for循环不适用于退化的C样式数组。
处理数值参数
命令行参数始终以字符串形式传递,即使提供的值本质上是数字。要将命令行参数当作数字使用,必须先将其从字符串转换为数字。不幸的是,C++在这一点上比预期更麻烦一些。
执行此操作的C++方法如下:
|
|
当以输入“567”运行时,该程序打印:
|
|
stringstream的工作原理与std::cin非常相似。在这种情况下,我们使用argv[1]的值对它进行初始化,以便可以使用操作符»将值提取为整数变量(与使用std::cin相同)。
在以后的一章中,我们将更多地讨论std::stringstream。
操作系统会预处理命令行参数
在命令行中键入内容(或从IDE运行程序)时,操作系统负责根据需要转换和路由该请求。这不仅涉及运行可执行文件,还涉及解析所有参数,以确定如何处理这些参数并将其传递给应用程序。
通常,操作系统有处理双引号和反斜杠等特殊字符的特殊规则。
例如:
|
|
打印:
|
|
通常,以双引号传递的字符串被认为是同一字符串的一部分:
|
|
打印:
|
|
大多数操作系统都允许您通过反斜杠加双引号来传递原始的双引号:
|
|
打印:
|
|
其他字符也可能需要反斜杠转义,这取决于您的操作系统如何解释它们。
结论
命令行参数为用户提供了一种很好的方式,可以在程序启动时将输入数据传递给程序。当然,程序中也需要判断传入参数的有效性。