几小时前我在C ++中问了一个类似的关于命令行参数的问题。现在我有另一个问题,据我所知,命令行参数将像argv数组中的字符串一样保存。所以将主题与字符串进行比较应该是合乎逻辑的,但它不能按照我想要的方式工作,看看这段代码:
#include <iostream>
using namespace std;
int main(int argc,char** argv)
{
if (argv[2]=="stack") cout << "right";
cout << argv[2];
return 0;
}
现在我将此命令传递给名为zero.exe的已编译应用程序;
zero.exe stack
输出应为&#34; rightstack&#34;,但if
命令将跳过,只有cout << argv[2];
将执行,因此只有堆栈将显示在监视器上。它显示"stack"
已保存到argv[2]
,因此if (argv[2]=="stack")
应该有效,但事实并非如此。问题出在哪里?
答案 0 :(得分:8)
由于历史原因,参数作为C风格的字符串传递;也就是说,每个都是一个指向字符数组的指针,带有一个零值字符来标记结尾。同样,字符串文字(如"stack"
)是一个简单的字符数组。
您的代码会比较两个指针,即使字符串值相等也不会相等。要比较字符串,请将一个(或两个)转换为std::string
:
#include <string>
std::string arg2(argv[2]);
if (arg2=="stack") std::cout << "right\n";
或使用C库函数比较C风格的字符串;这可能更有效,但也更难阅读:
#include <cstring>
if (std::strcmp(argv[2], "stack") == 0) std::cout << "right\n";
此外,参数从1开始计算,程序名称为argv[0]
,因此您可能希望测试argv[1]
而不是argv[2]
。
答案 1 :(得分:2)
问题是argv[2]
是不同的“堆栈”,而不是程序中的字符串文字“堆栈”。
毕竟这是C ++,如果你按照你的方式比较两个字符串,你只需比较它们的地址。
编辑:
在您的示例中,zero.exe stack
,argv[0]
包含程序名称,argv[1]
包含“堆栈”,因此您也可以选择一个。
更多编辑:
我想我看到了编号混淆的来源......如果你在Visual Studio调试器下运行,你可以在项目的属性页面中输入命令行参数,在这种情况下,zero.exe
将成为argv [1],是的。程序本身的名称将始终位于argv [0]。