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;
}

ここで、このコマンドをゼロ.exe という名前のコンパイル済みアプリケーションに渡します。

zero.exe stack

出力は「rightstack」である必要がありますが、ifコマンドはスキップcout << argv[2];されて実行されるだけなので、スタックのみがモニターに表示されます。"stack"に保存されていることが示されているため、機能するはずですがargv[2]、そうif (argv[2]=="stack")ではありません。問題はどこだ?

4

2 に答える 2

7

歴史的な理由から、引数は C スタイルの文字列として渡されます。つまり、それぞれが文字の配列へのポインターであり、値がゼロの文字が末尾を示します。同様に、文字列リテラル ( など"stack") は文字の単純な配列です。

コードは 2 つのポインターを比較しますが、文字列値が等しい場合でも等しくありません。文字列を比較するには、一方 (または両方) を次のように変換します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].

于 2012-06-19T17:26:03.547 に答える
2

問題は、プログラムにある文字列リテラルの「スタック」argv[2]とは異なる「スタック」であることです。
結局のところ、これは C++ であり、2 つの文字列を同じように比較すると、それらのアドレスのみを比較することになります。

編集:
あなたの例でzero.exe stackargv[0]、プログラム名とargv[1]「スタック」が含まれているため、1つずれています。

さらに編集:
番号付けの混乱がどこから来ているのかがわかると思います... Visual Studioデバッガーで実行している場合、プロジェクトのプロパティページにコマンドラインパラメーターを入力できます。その場合、zero.exeargv[1 ]、 はい。プログラム自体の名前は常に argv[0] にあります。

于 2012-06-19T17:22:00.470 に答える