-13

C++11 スレッドをいじる簡単なテスト プログラムを作成しました。

#include <iostream>
#include <stdlib.h>
#include <thread>
using namespace std;

void tee(int civ)
{
    for(int loop=0; loop<19; loop++, civ++)
    {
        civ = civ%19;
        cout << loop << "\t" << civ << endl;
        this_thread::sleep_for(chrono::milliseconds(300));
    }
}

void koot()
{
    while(true)
    {
        cout << ":) ";
        this_thread::sleep_for(chrono::milliseconds(300));
    }
}

int main(int argc, char *argv[])
{
    thread saie(tee, atoi(argv[1])),
        kamaa(koot);
    saie.join();
    kamaa.join();

    return 0;
}

コマンド ライン引数を指定する限り問題なく動作しますが、指定しないとクラッシュします。これはどのように解決できますか?引数の数を確認しようとしましたが、存在する場合は役に立ちませんでした。

編集:次の行を追加する必要がありました:

if(argc < 2) return 1;
4

4 に答える 4

7

アクセスしているためクラッシュします

argv[1]

コマンドライン引数 (プログラムの名前以外) があればそれを保持します。が 1 より大きいかどうかを確認する必要argcがあります。なぜ 1 より大きいのですか? 最初のコマンド ライン引数はプログラム自体の名前であるためです。は常にargcより大きくなり0ます。そして、インデックス作成は から始まり0ます。したがってargc == 1、 のみargv[0]が有効です。

#include <iostream>
int main(int argc, char* argv[])
{
  // no need to check argc for argv[0]
  std::cout << argc << " " << argv[0] << "\n";
}
于 2013-01-18T17:49:34.937 に答える
4

argv[1]が null であるため、 への呼び出しでクラッシュが発生しますatoi()。C++ の配列インデックスはゼロから始まることに注意してください。

于 2013-01-18T17:48:46.363 に答える
3

かどうかargc > 1を確認せずにアクセスしようとするためargv[1]

これを解決する方法は、最初に確認してargc > 1から argv[1] にアクセスすることです。

int main(int argc, char *argv[])
{

    if(argc > 1){
    thread saie(tee, atoi(argv[1])),
        kamaa(koot);
    saie.join();
    kamaa.join();
   }
    return 0;
}

覚えておくべきポイント:

  1. argcデフォルトは 1 です。これは、no を保持する引数カウンターです。プログラムに渡される引数の。プログラムが実行可能ファイルの名前 (およびパス) を取得するため、デフォルトでは 1 です。

  2. argvNULL で終了する文字配列 (または文字列) の配列を保持します。argv[0]常に実行可能ファイルの名前を保持します。

  3. ユーザーが常に引数を入力すると想定しないでください。argv将来的にまたは任意の配列にアクセスしている間は、常に境界チェックを行います。

于 2013-01-18T17:48:53.770 に答える
2

代わりに次のコードを試してください。

int main(int argc, char *argv[])
{
    if(argc < 2) {   cout<<"No command line arguments found\n Aborting!\n"; return 1;}
    else         {   thread saie(tee, atoi(argv[1])),kamaa(koot);}
    saie.join();
    kamaa.join();

    return 0;
}

存在しないコマンド ライン引数 argv[1] にアクセスしようとしています。コマンドライン引数が存在するかどうかを常に確認することをお勧めします。

于 2013-01-18T17:57:44.563 に答える