• 締切済み

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

みんなの回答

回答No.4

>整数のデータで計算を行うと、正常に動くのですが…。 オートで確保した配列が巨大過ぎるのが原因。 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)
回答No.3

コンパイラは何でしょうか? スタックサイズはコンパイラの設定より限定されています。 double c[50000]; double d[50000]; double e[50000]; 最近の環境だと、大体 double = 8byte 1200000byteでおよそ1.2MB以上のスタックサイズが必要です。 BCCやVCとかだとデフォルトスタックサイズが1Mなので、 スタックオーバーフローとなります。 コンパイラのスタックサイズの設定を変更するか、 配列のサイズをもう少し少なくすれば動作すると思います。

  • nda23
  • ベストアンサー率54% (777/1415)
回答No.2

>double c[50000]; double d[50000]; double e[50000]; 自動変数で、こんなに大量のメモリを使用してはダメとしたもの。 「自動変数」とか「スタック」とかで検索してみてください。 ヒント:static 賢くは実行時にローカルヒープから必要なメモリを確保するように しますが、ポインタ+構造体の知恵が必要です。

  • php504
  • ベストアンサー率42% (926/2160)
回答No.1

double c[50000]; double d[50000]; double e[50000]; 配列のサイズが大きすぎるんじゃないでしょうか 8バイト*15万で120万バイトですもんね 1MBのスタックでも足りません

関連するQ&A