アプリ版:「スタンプのみでお礼する」機能のリリースについて

以下のプログラムをコンパイル・実行しようとすると、コンパイルはエラーなくできますが、実行すると「プログラムは動作を停止しました」という表示が出て、エラーになってしまいます。
たぶんatoi()が原因だと思うのですが、何が問題なのでしょうか?
それとも環境の問題でしょうか?
どなたかご存知の方がいらしたら教えてもらえないでしょうか。
<環境>
VISTA、VC++
//------ここから----------
#include <stdio.h>
#include <stdlib.h>

#define AAA atoi(argv[1])
#define BBB atoi(argv[2])
#define CCC atoi(argv[3])
#define DDD atoi(argv[4])
#define EEE atoi(argv[5])
#define FFF atoi(argv[6])
#define GGG atoi(argv[7])

int main(int argc, char **argv)
{
FILE *fo;

int i, j, k, l, m, v, cnt1;
int v_tmp = CCC;
int x_cnt;
int y_cnt = 0;
int cnt = 0;
int arr[8190];

if(argc != 9){
printf("引数の数が違います。\n");
printf("使用法:<プログラム名><AAA><BBB><CCC>\n");
printf("<DDD><EEE><FFF><GGG><出力ファイル名>");
exit(1);
}

if((fo = fopen(argv[8], "w"))==NULL){
printf("can not open file\n");
exit(1);
}

v = v_tmp;

for(l=0; l<AAA; l++){
arr[l] = v;
cnt++;
if(cnt == FFF){
v += DDD;
cnt = 0;
}
}

for(i=0; i<BBB; i++){
m = 1;
cnt1 = 0;
x_cnt = 0;
while(x_cnt < AAA){
fprintf(fo, "%04x", arr[m]);
x_cnt++;
if(!(x_cnt%2))
fprintf(fo, "\n");
cnt1++;
if(cnt1%2){
}else{
m += 3;
}
m -= 1;
}
y_cnt++;
if(y_cnt == GGG){
v_tmp += EEE;
y_cnt = 0;
v = v_tmp;
cnt = 0;
for(l=0; l<AAA; l++){
arr[l] = v;
cnt++;
if(cnt == FFF){
v += DDD;
cnt = 0;
}
}
}
}

fclose(fo);

return 0;
}

A 回答 (8件)

printf デバッグするならバッファリングを止めるかそのたびに fflush(stdout); する.


もしくは stderr に fprintf.
    • good
    • 0

>たぶんatoi()が原因だと思うのですが


「たぶん」じゃくて、どこまで実行できているのかをまず確認しましょう。
デバッグモードでトレースしてもいいですし、適当なprintfを随所にちりばめるだけでかなりのことがわかりますよ。

デバッグの基本は、エラーの発生個所を絞り込むことからです。
    • good
    • 0

とりあえず、#defineで定義しているatoi()を全てmain()内に展開しましょう。


で、少しずつ動かすのが大事です。
とりあえず、コーディングしたとしても、部分部分をコメントアウトし、どこまで
動作したかぐらいは確認しましょう。
# 因みに printf()等でデバッグ情報出力しようとしても、書込バッファが一杯にならないと
# 出力されないです。
# こまめに調査していくしかないですね。

取り急ぎ、#defineで定義するのは 記号定数(及びそれに対して置き換える定数)・マクロ関数
というのが仕様です。
今回は定数ではなく関数(しかも変数付)を定義しているのがもしかしたら影響しているかもしれないです。

そうだとしたら最初に記述したように #defineで定義しているatoi()をmain()内に
直接記述すれば動作するかと思いますし、それでも動作しないのであれば
ポインタ関連を使用しているのは argv[]ぐらいですので、そこに値が
思った通りに入っていないが疑わしいです。
#この場合は「v_tmp = CCC;」を引数チェックの後に実行すべきですね。
#Cの作法上からしても引数チェック前にこういったポインタの使用は
#さけるべきです。
    • good
    • 0

>後世の為に、何でこの不具合が分からなかったのかお教えお願い出来ないでしょうか?



そりゃまあ、気づかないこともあるでしょう。
人間がすることですから。
    • good
    • 0

>#define AAA atoi(argv[1])


・・・
>#define GGG atoi(argv[7])

こういう発想が不可思議です。
どうしてこうしたことが必要と思われたのでしょう?
何かに記載されていたのでしょうか?
    • good
    • 0

まず、プログラム実行開始時に引数の数が3個未満だった場合の不具合について


>> int v_tmp = CCC;

CCCは(atoi(argv[3]))ですが、引数が3個未満だった場合、argc[3]は不定アドレスのポインタです。
そんな箇所を参照すればエラーが起こって当たり前です。
VCのデバッグモードで実行すれば一発で指定した行で止まります。

後世の為に、何でこの不具合が分からなかったのかお教えお願い出来ないでしょうか?

また、defineもこんな使い方はしません。
    • good
    • 0

回答ではないことを先に言っておきます。



自分ならatoiが問題と思った時点でAAAやBBBの値を確認しますね。
問題なければdebugモードで実行してどこまで処理が進むかを確認します。

あとdefineなんて使わずにargcの値を確認したら真っ先にint変数にでもargvの値を代入したほうがいいでしょう。
そうでないとAAAやBBBと記載されている回数だけatoi関数が呼ばれるので処理の無駄です。

参考になれば幸いです。
    • good
    • 0

実行時にどういう引数を与えたときに


そのエラーが出るのですか?

本題とはそれるかもしれませんが、
「#defineをこんな風に使ってはいけない見本」のような気がします。
そんな気がするのは私だけかもしれませんが…。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!