標準的な方法はargv
、コマンド ライン引数にアクセスするために を使用することです。一部のアーキテクチャでは、これを行う他の方法があることに気付くかもしれませんが、それらは移植可能ではない可能性が高く、標準的な慣行に従わない理由はあまりないようです。値を int に読み込むには、次のいずれかを使用できますstrtol
long n = strtol( argv[1], NULL, 0 );
(入力とエラー処理をもう少し制御できるので、strtol
toを使用することを好む傾向があることに注意してください-ただし、それほど多くはありません)atoi
次のようにストリームを使用することもできます。
istringstream ss( argv[1] );
long n;
ss >> n;
ただし、あなたがやろうとしていることについて2つのことが気になります。まず、実行時に設定された変数値を関数内にカプセル化する必要があります。論理的には、関数と外部の影響 (コマンド ライン パラメーター) の間に目に見えない依存関係があるため、コードの保守性が低下します。そのため、関数の決定論的プロパティが損なわれます。実際には、これにより関数のテストがはるかに困難になります。特に、実行前にプログラムで値を設定する方法がないため、自動化された単体テストを使用する場合はそうです。
a
第二に、これを複雑にするかのように、名前のない名前空間内のコンパイル単位に変数のスコープを制限しようとしています。これには、2 つの望ましくない影響があります。まず、テスト ハーネスやその他のコードはこの変数を認識できないため、自動化された UT の観点からすると、これはかなり悪いことです。次に、a
コンパイル単位内で事実上「グローバル」になります。このコンパイル ユニットの関数内で、 がいつどのようにa
使用されるかを追跡するのは非常に難しく、コードを保守する人にとっては少し頭の痛い問題です。実際に問題を引き起こすマルチスレッドを使用していないと仮定します。
argv[1]
パスしたくない理由を知りたいのですがprint_from_external_file()
、これが最善の方法だと本当に思います。この変数を文字列として直接渡すことも、int に変換することもできないと思われる場合は、渡すことができるコマンド ライン パラメーターまたは構成オブジェクトを作成することを検討してください。
configuration c( argc, argv ); // This contains the hard work of parsing the CL
print_from_external_file( c );
これにより、コマンド ラインを解析するという大変な作業のほとんどが隠されます。さらに良いことに、CL パラメータに真の意味を追加できます。a
変数がカタログ番号を表しているとしましょう。configuration
クラスのコンストラクターはこれを簡単に実行できます。
configuration::configuration( int argc, char* argv[] )
{
// ...
catalogNo_ = strtol( argv[1], NULL, 0 );
そして、アクセサーが追加された場合:
int configuration::get_catalog_no() const { return catalogNo_; }
print_from_external_file()
次に、私たちが行っていることでより明白になります。
void print_from_external_file( const configuration& c )
{
cout << c.get_catalog_no() << endl;
}