- 締切済み
C言語のプログラミングで困っています
C言語を勉強しています。まだまだ初心者で分からないことだらけなのですが、今回はファイル入出力の部分が分からず苦戦しています。 『100個の実数が入った2つのテキストファイルから数値を読み込み、 絶対値を求めるなどの計算をする』プログラムを作成しているのですが、 コンパイルし実行すると強制終了してしまいます。 プログラムは、 void main(void) { FILE *fp; double c[50000]; double d[50000]; double e[50000]; int n = 0; int m = 0; int i = 0; char fname[80]; char fname2[80]; printf("ファイル名 : "); gets(fname); if((fp = fopen(fname, "r")) == NULL){ printf("ファイルがオープンできません\n"); exit(1); } printf("\n"); while (fscanf(fp,"%lf",&c[i])!=EOF){ printf("%3d : %3lf",++n,c[i]); printf("\n"); i++; } printf("\n"); i=0; n=0; printf("ファイル名 : "); gets(fname2); if((fp = fopen(fname2, "r")) == NULL){ printf("ファイルがオープンできません\n"); exit(1); } printf("\n"); while (fscanf(fp,"%lf",&d[i])!=EOF){ printf("%3d : %3lf",++n,d[i]); printf("\n"); i++; } …(以下計算) のようになっています。 整数のデータで計算を行うと、正常に動くのですが…。 コンパイルしてもエラーが出ないので、どこが悪いのかわからず困っています。 どなたか教えていただけないでしょうか。お願いしますm(_ _)m
- みんなの回答 (4)
- 専門家の回答
みんなの回答
- chie65536(@chie65535)
- ベストアンサー率44% (8740/19838)
>整数のデータで計算を行うと、正常に動くのですが…。 オートで確保した配列が巨大過ぎるのが原因。 intなら1つ4バイトでギリギリ動く大きさだったが、doubleは1つ8バイトで、使用するメモリ量が2倍になり、メモリがパンクしてしまい「実行時に強制終了」になっている。 それと while (fscanf(fp,"%lf",&c[i])!=EOF){ も問題がある。 ファイルが尽きてfscanfからEOFが返された場合は良いが「数値として認識できない文字がファイル中にあった場合」には、無限ループする。 fscanfは「数値として認識できない文字」に出会うと、その文字をストリームに残したまま「その時点までで正常に変換して変数に代入した数」を返す。 つまり「最初に変な文字に出会うと、変数に何も代入せず、0を返す」場合がある。つまり「EOFを返してくれない」のだ。 「ストリームにある変な文字」は「消費されずにストリームに残っている」ので、次のfscanfも、次の次のfscanfも、同じように「変数に何も代入せず、0を返す」のが永久に続く。 つまり while (fscanf(fp,"%lf",&c[i])!=EOF){ は「永久に止まらなくなる事がある」って事。 まあ、実際には「iが配列の要素数の50000を超え、不正なメモリをアクセスして止まる」だろうから「永久に止まらない」って事は無いが。 とにもかくにも「fscanfが0を返した瞬間、ジ・エンド」って事は間違い無い。 while (fscanf(fp,"%lf",&c[i])!=EOF){ ではなく while (fscanf(fp,"%lf",&c[i])==1){ にして「正常に変換して変数に代入できた個数が1個の間、ループする」じゃないとダメ。
- aris-wiz
- ベストアンサー率38% (96/252)
コンパイラは何でしょうか? スタックサイズはコンパイラの設定より限定されています。 double c[50000]; double d[50000]; double e[50000]; 最近の環境だと、大体 double = 8byte 1200000byteでおよそ1.2MB以上のスタックサイズが必要です。 BCCやVCとかだとデフォルトスタックサイズが1Mなので、 スタックオーバーフローとなります。 コンパイラのスタックサイズの設定を変更するか、 配列のサイズをもう少し少なくすれば動作すると思います。
- nda23
- ベストアンサー率54% (777/1415)
>double c[50000]; double d[50000]; double e[50000]; 自動変数で、こんなに大量のメモリを使用してはダメとしたもの。 「自動変数」とか「スタック」とかで検索してみてください。 ヒント:static 賢くは実行時にローカルヒープから必要なメモリを確保するように しますが、ポインタ+構造体の知恵が必要です。
- php504
- ベストアンサー率42% (926/2160)
double c[50000]; double d[50000]; double e[50000]; 配列のサイズが大きすぎるんじゃないでしょうか 8バイト*15万で120万バイトですもんね 1MBのスタックでも足りません