2012-06-19 41 views
1

幾個小時前,我問過關於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 

輸出應爲「rightstack」,但if命令將跳過並且僅cout << argv[2];將執行,所以只堆將監視器上顯示被。它顯示"stack"被保存到argv[2],所以if (argv[2]=="stack")應該可以工作,但事實並非如此。哪裏有問題?

回答

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]

+3

你說「你的代碼比較兩個指針,即使字符串值相等,它也不會相等。」這當然是這種情況,我不是在爭辯。但在其他情況下,例如如果在同一源代碼中有兩個相同的字符串文字,它們很可能會被摺疊,並且'(「test」==「test」)'將評估爲true。 –

+0

@Mike Seymour尼斯回答,非常感謝:)) – Nofuzy

+4

另一個整潔的技巧是'std :: vector (argv,argv + argc);' –

2

問題是argv[2]是一個不同的「堆棧」比您的程序中的字符串文字「堆棧」。
這就是C++畢竟,如果你按照你做的方式比較兩個字符串,你只是比較他們的地址。

編輯:
在你的榜樣,zero.exe stackargv[0]包含程序名稱和argv[1]包含「棧」,所以你也關閉的一個。

更多編輯:
我想我看到編號混淆來自哪裏......如果您在Visual Studio調試器下運行,您可以在項目的屬性頁中輸入命令行參數,在這種情況下,是的,zero.exe會成爲argv [1]。程序本身的名稱將始終在argv [0]中。

相關問題