2009-08-16 12 views
0

私のC++プログラムの比較に問題がありました。これは煮詰めたバージョンです。C++でのCの文字列比較の問題

#include "stdafx.h" 
#include <iostream> 
#include <windows.h> 
using namespace std; 
int main(int argc, char *argv[]) 
{ 
    if(argc>2){cout<<"3+Args"<<endl;}else//??? 
    if(argc==2){ 
     cout<<"2args"<<endl; 
     if(argv[1]=="/hide-icons"){} 
     if(argv[1]=="/show-icons"){} 
     if(argv[1]=="/reinstall"){setAsDefault();} 
     if(argv[1]=="/?"){showPossibleCommands();} 
     if(argv[1]=="/1"){cout<<"go"<<endl;FirstRun();} 
    }else{showPossibleCommands();cout<<argv[0]<<endl;} 
    return 0; 
} 

"programname.exe/1"を実行すると、私のプログラムは "2args"を書きますが、 "go"は書きません。私は明白な何かを欠いていますかあなたがケースになるだろうされていない使用している様々な文字列定数の開始と同じスポットへのポインタが...あればチェックしている==で試験することによりよう

+0

あなたは引数になりたい場合ははい、あなたは.... – Tom

答えて

18

argv[1]は、char*です。代わりにの内容をと比較するには、strcmpを使用してください。

+3

それともstricmpです大文字と小文字を区別しない –

+1

または最初のn文字だけをテストする場合はstrncmp。 –

+2

'stricmp()'は標準ではありません。 Chereは大文字小文字を区別しない文字列比較を行うための実際の標準C(またはC++プログラマーに頼んでください)の方法はありません。 GCCはstrcasecmpを提供し、VC++はstricmpを提供します... –

5

問題は、あなたのコードは、文字列へのポインタではなく、刺し傷自体を比較することです。

文字列比較関数の呼び出しとの比較を置き換える必要があります。

など。

if(argv[1]=="/1"){cout<<"go"<<endl;FirstRun();} 

は、あなたがあなたのコードにstrcmpのプロトタイプを取得するにはstring.hのを含める必要があり

if(strcmp(argv[1],"/1") == 0) {cout<<"go"<<endl;FirstRun();} 

になります。

1

別のオプションは、文字列のはるかに優しいベクターにCスタイルの引数を変換し、代わりにそれらを処理することです:

#include <string> 
#include <vector> 

typedef std::vector<std::string> parameter_list; 

int 
cpp_main(std::string const& program_name, parameter_list const& params) { 
    for (parameter_list::const_iterator arg=params.begin(); arg!=params.end(); ++arg) { 
     if (*arg == "/hide-icons") { 
     } else if (*arg == "/show-icons") { 
     } else if (*arg == "/reinstall") { 
      set_as_default(); 
     } else if (*arg == "/?") { 
      show_help(program_name); 
     } else if (*arg == "/1") { 
      first_run(); 
     } else { 
      show_help(program_name); 
     } 
    } 
    return 0; 
} 

int 
main(int argc, char **argv) { 
    return cpp_main(argv[0], parameter_list(&argv[1], &argv[argc])); 
} 
+0

いいアイデア。しかし、その範囲外の配列にはアクセスすべきではありません。結果は定義されていませんが、通常、配列がメモリページの終わりにない限り動作します。 argv [0] + 1、argv [0] + argc) – iain

+0

コンストラクタは決してその範囲外の 'argv'を逆参照しません。これはSTLのオープン範囲で、 'argv [1]'で始まり 'argv [argc]'の前の要素で終わるようにコピーされます。 'end()'はSTLが実際に_ "コンテナの最後の値" _であることに注意してください。コンテナが配列の場合、これは配列の最後の要素に続く要素です。しかし、 'argv [argc]'のアドレスがアドレス範囲をオーバーフローする可能性は低いかもしれませんが、この標準が実際にこの問題に対して保護を提供していると思います。 –