2016-08-06 3 views
0

私はC++ 11にかなり新たなんだと私は本当に、コマンドライン引数はARGVポインタに解析されているどのようにそれを得ることはありません...C++ 11のコマンドラインパラメータ分離

私はこのコードを持っています:

int main(int argc, char* argv[]) 
{ 
    std::string curr_arg = ""; 

    std::string str_base = ""; 
    std::string str_subs_file = ""; 
    std::string str_subs = ""; 

    for(int i = 1; i < argc; i++) 
    { 
     curr_arg = argv[i]; 

     if(curr_arg == "-b" || curr_arg == "--base") 
     { 
      str_base = argv[++i]; 
     } 
     else if(curr_arg == "-f" || curr_arg == "--file") 
     { 
      str_subs_file = argv[++i]; 
     } 
     else if(curr_arg == "-s" || curr_arg == "--subs") 
     { 
      str_subs = argv[++i]; 
     } 
     else 
     { 
      std::cout << "Argument '" << argv[i] << "' is not recognised." << std::endl; 
      return -1; 
     } 
    } 
} 

私は1,2,3 = ./subs -bベース-saと私のプログラムを呼び出すと、b = 4,5,6; C = 6,7,8、私は私が得ることを期待しますif(curr_arg == "-s" || curr_arg == "--subs"ブロックに入力すると、 "a = 1,2,3; b = 4,5,6; c = 6,7,8"という引数が入力され、代わりに "a = 1,2,3" 。 私は引数全体を引用符で囲むと動作することを知っていますが、それがどうして起こるのか分かりません。 私に説明できる人はいますか?

+3

';'はほとんどのシェルではコマンドセパレータです。これはCやC++とは関係ありません。 – Mat

+0

を脇に:本当に独自のCLIパーサーを作成したいですか?なぜ既存のものを使用しないのですか( 'boost :: program_options'、...)? –

+0

ああ、大丈夫、高速回答ありがとう! 私はちょうどそれが余計になることは本当に難しいことではないと思った –

答えて

3

C++では問題は発生していませんが、コマンドシェルでは問題ありません。あなたのシェルがコマンドセパレータとしてセミコロンを取っているからでしょう。

シェルはあなたのコマンドを./subs -b base -s a=1,2,3と解釈し、セミコロンを検出して次のコマンドを解釈します。これはb=4,5,6で、c=6,7,8と同じです。

それはかなり(ほとんどのUnixシェルに取り組むべき)と入力するのと同じです:

echo abc; sleep 5; echo def 5 seconds later 

これは、「ABC」を印刷しますが、その後「5秒後DEF」5秒とプリントのために眠ります。

ソリューション:

./subs -b base -s "a=1,2,3;b=4,5,6;c=6,7,8" 

か、のようなセミコロンをエスケープできます:

./subs -b base -s a=1,2,3\;b=4,5,6\;c=6,7,8 

どちらのバージョンを あなたが望む結果を得るために、次のような引用符で一部a=1,2,3;b=4,5,6;c=6,7,8をカプセル化することができ(すべてではないにしろ)ほとんどのUNIXシェルとWindowsのcmdでも動作するはずです。

+0

ああ私はこれについて全く考えなかった... あなたの答えをありがとう! それから、あなたはそれを言いましたか、別のセパレータを使用する必要があります... –