質問
testというプログラムを作成しました:
#include<stdlib.h>
#include<iostream>
int main()
{
std::cout<<system("..\\add\\debug\\add.exe 4 8");
while(true);
return 0;
}
add.exeの構成
#include<stdlib.h>
int main(int argc,char **argv[])
{
int n=((unsigned)argv[1]);
int m=((unsigned)argv[2]);
return(n+m);
}
テストを実行すると、次のようになります
6841420
パラメータ4および8を使用してテスト実行を追加し、それらの値の合計(12)を返すためにaddを実行し、テストでそれを画面に表示しようとしました。どのようにして6841420を入手し、どうすれば修正できますか?
解決
問題は、ポインター値を整数に変換していることです。引数は、Cスタイル文字列(const char*
)としてプログラムに渡されます。まず、atoiなどのAPIを使用して、これらを文字列に変換する必要があります。
#include<stdlib.h>
int main(int argc,char *argv[])
{
int n= atoi(argv[1]);
int m= atoi(argv[2]);
return(n+m);
}
編集
他の人が指摘したように、プログラムに実際に2つのパラメーターが渡されていることを確認するために、エラーチェックも行う必要があります。
他のヒント
add.exeは文字列へのポインタを符号なしintにキャストしているため、数字ではなくメモリ内の位置を追加しています。
sscanfを使用します(または、別の回答で示唆されているように、atoi-おそらく簡単です)。
これはおもちゃとしては大丈夫かもしれませんが、参考までに、main()から整数の全範囲を返すことができると期待することはできません。最初に、system()はさまざまな値を番兵として使用します(たとえば、-1および127)。そのため、実行の失敗とそれらの値の正当な結果との違いを知ることができません。第二に、シェルは戻り値の範囲を8ビットのみに制限する場合があります(追加のステータス情報に残りのビットを使用します)。
atoi()またはsscanf()を使用してargv []要素を文字列から実際の整数に変換することに関する答えは、まさにそのとおりです。
ただし、テストケースには別の問題があります。 system()
の戻り値は、実行されたプロセスの終了ステータスであり、プラットフォームに少し依存しています。ただし、ほとんどのプラットフォームでは、値0
がコマンドが正常に実行され、最終的にexit(0)
自体が呼び出されることを意味するように調整されています。 Windowsはそれだけに準拠しています。
cout<<system(...)
行はそのステータス値を出力しています。多くのプラットフォーム(特にPOSIX準拠のもの)では、プロセスが異常終了せずに実行された場合、ステータスコードの下位バイトはゼロになり、上位バイトは値が255以下であると仮定してexit()
に渡されます。
実際に終了ステータスを使用して、成功/失敗よりもはるかに多くの情報を親プロセスに伝えることは、プラットフォームに大きく依存しており、それを行うためのはるかに良い方法があります。