• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:エラーがどうしても解消しません。)

エラーの解消方法は?

このQ&Aのポイント
  • エラーがどうしても解消しません。コーディング無視、コメント無しです。
  • 使用環境はXP-sp2 CPAT for Boland C++ Compiler Ver2.31 Boland C++ Compiler5.5 複数のテキストファイルを一つのファイルにまとめるプログラムです。33行目以降は出力です。読込48ファイル目でエラーが出てしまいます。
  • 解決方法はあるのでしょうか。

質問者が選んだベストアンサー

  • ベストアンサー
  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.3

OSには「同時にファイルを開ける数」に上限があります。 この上限には「すべてのプログラムを通した全部の合計」と「1つのプログラムでの合計」など、色々あります。 また、Cコンパイラの場合、fopenの実装によっては「ファイルポインタは、内部的な、有限個の配列の、1つの要素を返す」と言う実装をしている場合があるのです。 つまり、内部的に FOPEN_MAX=50 FILE ___file_table[FOPEN_MAX]; みたいな感じで有限個の配列があって、配列の要素の個数がFOPEN_MAX個しかないのです。 で、stdinは___file_table[0]のポインタを差し、stdoutは___file_table[1]のポインタを差し、stderrは___file_table[2]のポインタを差していて、最初に3つ使用済みになっています。 そして、fopenが呼ばれるたびに、___file_table[3]、___file_table[4]のポインタが順に返されます(もちろん、クローズされて未使用になれば、またそれが再利用されて返されますが) で、この配列がクローズされずに全部埋まっちゃうか、オープン数が1プログラムの上限を越えるか、OSの上限を超えれば「もうダメぽ」って感じでエラーが出て止まります。

w_t_
質問者

お礼

回答ありがとうございます。 みなさんの回答内容が一緒なので、*fpはオープンして使ったらクローズするを心がけて、作り直したいと思います。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (3)

  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.4

因みに。 Windowsの前身のMS-DOSでは、コンベンショナルメモリを増やす方法として、CONFIG.SYSファイルに「同時オープン数の上限」が記述出来ます。 例えば FILES=16 とか。 MS-DOSの起動ドライブのCONFIG.SYSに上記のように書いておくと、同時に開けるファイルが16個だけになります。 そのような環境では、質問者さんのプログラムは、もっと早い段階でエラーで止まります。 なので「ファイルを開いて使い終わったら、使いもしないのに開きっぱなしで放置」したりしてはいけません。 複数のファイルを1つにするプログラムを書く場合は、 1.出力ファイルを開く 2.1つ目の入力ファイルを開く 3.中身を読み書きしてコピー 4.1つ目の入力ファイルを閉じる 5.2つ目の入力ファイルを開く 6.中身を読み書きしてコピー 7.2つ目の入力ファイルを閉じる 8.3つ目の入力ファイルを開く 9.中身を読み書きしてコピー 10.3つ目の入力ファイルを閉じる 11.出力ファイルを閉じる のような書き方をしましょう。 そうすれば FILE *ifp,*ofp; の2つのファイルポインタさえあれば処理できます。

w_t_
質問者

お礼

丁寧に書いて頂ありがとうございます。 大変参考になりました。 今回、質問投稿は初めてなのでポイントの付け方が分かりません。 皆様にと思うのですが、ごめんなさい。

全文を見る
すると、全ての回答が全文表示されます。
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.2

ひょっとしてファイルオープンに失敗するというエラーですか? 条件(OSとかそのへん)によって違いはありますが、 開きっぱなしにできるファイルの数には制限があります。 質問にあるコードではクローズをどのタイミングでやっているのかわかりませんが、 >7: FILE *fp[99],*fpo; というのをみるに、一辺にオープンして最後にまとめてクローズしようとしてませんか?

w_t_
質問者

補足

回答ありがとうございます。 ファイルのオープンに失敗します。 一旦、50のファイルをオープンしてから、32行目以降にてfor文でfname1にオープンしたファイルの内容をコピーして*fp[99]を閉じてます。

全文を見る
すると、全ての回答が全文表示されます。
  • hidebun
  • ベストアンサー率50% (92/181)
回答No.1

stdio.hの中に、FOPEN_MAXという値が定義されています。 これが50になっているのでしょう。 stdin, stdout, stderrがプログラム開始時に3ファイル分使用されて しまうので、50-3=47個が、同時に開くことが可能な最大数になります。 この値を変更する方法があるかもしれませんが、それよりもロジックを 見直したほうが良いでしょう。

w_t_
質問者

お礼

早速の回答ありがとうございます。 stdio.h の中身がその様になっていたとは思っておりませんでした。 ロジックの見直しをがんばってやってみたいと思います。 関数も余り知らないので、知っている関数を使って一生懸命考えたあげく出たものです。 ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • Expression: nptr != NULL

    デバックではエラーが出なかったのですが、プログラムを走らせた所タイトルのような line:68 Expression: nptr != NULL のエラーが出ました。何が悪いのか分かりません。よろしければ、ご教示お願いします。 68行目もどこか書いておきました。 #include<stdio.h> #include<math.h> #include<string.h> #include <stdlib.h> #include <string.h> #include <windows.h> #include "conio.h" FILE *input; char fname[30]; int keisan(void); int main(void){ char *ret,infname[60],csv[]=".csv"; loop: printf("読み込むファイル名を入力してください\n"); scanf("%s",&fname); ret=strstr(fname,csv); if(ret!=NULL){printf("拡張子[.csv]を入力しないでください\n");goto loop;} strcpy(infname,fname); strcat(infname,csv); input=fopen(infname,"r"); if(input==NULL){ printf( "%sファイルが開けません\n",infname); return -1; }else{ keisan(); } fclose(input); return 0; } int keisan(void){ FILE *output; char outfname[60]; char str[256]; char *n,*nouse; int k=0; double n1,n2,time=60,times; int start=2; int line=0; strcpy(outfname,fname); strcat(outfname,"1.csv");//出力ファイル形式 output=fopen(outfname,"w"); while(fgets(str,256,input)!=NULL){ line++; if(line>=start){ k++; times=(double)k/time; n=strtok(str, ",");//1行目 n=strtok(NULL,",");//2行目 n1=strtod(n,&nouse); n=strtok(NULL,",");//3行目 n=strtok(NULL,",");//4行目 n2=strtod(n,&nouse);   ←←←68行目 printf("%d,%lf,%2.2lf,%2.1lf \n",k,times,n1,n2); fprintf(output,"%d,%lf,%2.2lf,%2.1lf \n",k,times,n1,n2); } } fclose(output); return 0; }

  • CSVファイルの入出力と計算

    C言語の質問です。 勉強不足で聞くのは申し訳ないのですが、 自分であれこれとやってみて、どうしていいのか分からなくなってしまいました。 csvファイルの中身は、6行目までは不要な文字列などが入っていて、7行目から使いたい数値となっています。その数値は5桁と分かっています。 さらに、データ数としては、約300000行~10000000行とデカイ上に定まっていません。 その数値に値をかけて変換してファイルとしてだしたいのですが、どうすればよいのでしょうか? 下のようなイメージ↓(値はテキトー) *********************************** 元ファイル→掛ける値→後ファイル 54321→→ *10/12365→ 1.4243 : : : : ************************************ 以下は自分で書いたものですが、 ????????????にしてあるあたり(ファイルを読み込む部分) がどうすればいいかわかりません。 変数が色々あるのは迷走の証です。 どうぞ、よろしくお願いします。 int main(){ FILE *in,*out; char fname1[30],fname2[30]; char s[5]; double n1; int n,i=0; int start=7; int line=0; printf("読み込むファイル名を入力してください\n"); scanf("%s",&fname1); in=fopen(fname1,"r"); out=fopen(fname2,"r"); if(in==NULL){ printf( "ファイルが開けません\n",fname1); return -1; } else{ ???????????????????? ?????????????????? printf("%d \n",n1); fprintf(out,"%s \n",n1); } } printf("書き込むファイル名を入力してください\n"); scanf("%s",&fname2); fclose(in); fclose(out); return 0; }

  • getsをscanfで書き直すにはどうしたらよいですか?

    現在。行数を数えるプログラムを例をみながらエディダに入力してコンパイルしてみたのですが、gets関数ではエラーが出てそれ以上すすまないです。 他の掲示板なんかをみると、getは危険だからscanfを使うといいですよと書いてあったのですが、書き換えかたがよく分からないのです。 *以下が問題にしているソースです。 /* ************************************* */ /* */ /* 行を数えるプログラム */ /* */ /* ************************************* */ #include <stdio.h> #include <stdlib.h> void main(void) { FILE *fp; char fname[256]; int c; int count; printf("ファイル名:"); if (gets(fnama) == NULL) { /* この部分 */ printf("入力エラーが発生しました。\n"); exit (-1); } if ((fp = fopen(fname,"r")) == NULL) { printf("ファイル '%s'をオープンできませんでした。\n",fname); exit (-1); } while ((c fgetc(fp)) != EOF) { if (c == '\n') { count++; } } printf(">>> ファイル %s は %d 行です。\n",fname,count); fclose(fp); }

  • ダンププログラムの結果表示で2バイトの場合

    ダンププログラムを作っています。 右のファイルの中身を表示する際に、16個目のデータが2バイト(漢字、全角文字など)だった場合、正しく表示されません。 改行前に2バイト目を表示したいのですがどうしたらよろしいでしょうか。 実行結果 /*----------------------- ..printf("ダンプ 表示するファイル 名を入力してくだ さい(ESC.キーで I了)\n");....... .printf("\n");.. ......scanf_s("% s",.fname);..... .if(error.=.fope n_s(&fp,.fname,. "rb").!=..0).{.. ...printf("ファ Cルがオープンで ォません\n");.... -----------------------*/ #include <stdio.h> #include <string.h> void DispData(void); FILE *fp; int main(void) { errno_t error; // エラーコード char fname[64] = { 0 }; // ファイル名 while(1) { printf("ダンプ表示するファイル名を入力してください(ESC キーで終了)\n"); printf("\n"); scanf_s("%s", fname); if(error = fopen_s(&fp, fname, "rb") != 0) { printf("ファイルがオープンできません\n"); } else { DispData(); break; } } printf("\n"); return 0; } void DispData(void) { int i = 0; int n; long addr = 0; unsigned char buf[16]; printf("ADRESS "); for(i=0; i<16; i++) { printf(" %02X", i); } printf(" DATA\n\n"); // ファイルの終了までファイルの内容をbufに1バイトサイズ、16要素で読み込む while( (n = fread(buf,sizeof(unsigned char),16,fp)) > 0) { //アドレスの表示 printf("%08lX ",addr); //読み込んだファイルの内容を16進数で表示 for(i = 0;i < n;i++){ printf("%02X ",buf[i]); } //16個に満たない分はスペースを表示 if(n < 16) { buf[i] = '\0'; for(;i < 16;i++){ printf(" "); } } printf(" "); for(i = 0;i < n; i++) { if((buf[i] >= 0x00) && (buf[i] <= 0x20) ) { putchar('.'); } else { putchar(buf[i]); } } printf("\n"); addr += 16; } }

  • テキストファイルの内容を2次元配列に格納したい

    課題で用意されたテキストファイルを読み込み、空白を区切りとする文字列の単位で配列に格納したいのですが、やりかたがわかりません。 ソースプログラムですが #include<stdio.h> #include<string.h> #include<ctype.h> #define MAX 1000 int TextSplit(char *fname, char (*SpStr)[50]); int main(void) { int i, n; char fname[MAX], SpStr[MAX][50]; int Split; FILE *fp; printf("input File =>"); scanf("%s", fname); Split = TextSplit(fname, SpStr); printf("\n %d[文字列数] \n", Split); return 0; } int TextSplit(char *fname, char (*SpStr)[50]) { int i, j, k; char Readstr[MAX]; FILE *fp; fp = fopen(fname, "r"); if(fp == NULL) { printf("ファイルオープン失敗"); return 1; } i = 0; while(fscanf(fp, "%s", SpStr) != EOF) { i++; } fclose(fp); return i; } 以上のソースプログラムですが、内容は「空白で区切る文字列の単位の総数を表示する」ものになっています。 今日の20時までに終わらせないといけないので、ご教授お願いします。 使ってるソフトはMicrosoft Visual Studioです。

  • 出力内容を新しいテキストファイルで保存するには?

    プログラム #include <stdio.h> #include <string.h> main() { char text[100]; char a[20], b[20], c[20], d[20], e[20], f[20]; char fname[20]; int i = 1; FILE *fp; printf("■ファイル名>>"); scanf("%s",fname); fp=fopen(fname,"r"); if((fp = fopen(fname,"r")) == NULL){ printf("ファイルをオープンできませんでした。\n"); return 1; } else{ printf("ファイルをオープンしました。\n"); } while( fscanf(fp, "%s", text) != EOF){ sscanf(text, "%[^,], %[^,], %[^,], %[^,], %[^,], %[^\0]", a, b, c ,d, e, f); printf("%d回目\n",i++); printf("全文:%s\n",text); printf("1つ目:%s\n",a); printf("2つ目:%s\n",b); printf("3つ目:%s\n",c); printf("4つ目:%s\n",d); printf("5つ目:%s\n",e); printf("6つ目:%s\n\n",f); } } テキストファイル ABCD,EFGH,IJKL,MNOP,QRST,UVWXWZ abcd,efgh,ijkl,mnop,qrst,uvwxyz あいうえお,かきくけこ,さしすせそ,たちつてと,なにぬねの,はひふへほ テキストファイルから文字列を読み込み、変換させて出力させた内容を他のテキストファイルに保存するにはどのようにしたらいいのでしょうか?

  • scanf文がうまくいかないのですが・・・

    下のようなプログラムを実行するとうまくいかないのですが、何故なのでしょう。 どうかお教えください。 #include<stdio.h> int main(void) { int i; char n; for(i = 0; i < 10; i++) { printf("nを入力してください>>>"); scanf("%c",&n); printf("%c\n",n); } return 0; }

  • C言語 複数ファイル操作について

    Cプログラミング初心者です。 論文などの何行も文章があるようなテキストファイル(ここでは1.txtとします)と、他に予め単語をいくつか登録しているテキストファイル(2.txt)を開き、1.txtを最初の行から一行ごとに読み込み、2.txtの中にある単語が1つでもその一行の文章中に含まれていたらその一行の文章を出力し、また次の行においても2.txtの中にある単語のいずれかが含まれているかどうかを調べて含まれている場合は出力…含まれていない場合は出力せずに次の行へ…といったようにこれを1.txt内の最後の行まで繰り返し行うプログラムを作りたいのですが、自分が作ったプログラムでは含む・含まない関係なく1.txt内の文章全てが出力されてしまいます。おそらく最初のwhile文あたりがおかしいのだろうという予想はつくのですがどのように直せばよいのかわからず悩んでいます。どなたか教えていただければ嬉しいです(;_:) #include <stdio.h> #include <stdlib.h> #include <string.h> #define N 1056 void delkaigyo(char *s1,char *s2){ char *p = s1; p=strstr(s1,s2); if(p!=NULL){ strcpy(p,p+strlen(s2)); delkaigyo(p+1,s2); } } int main(void){ FILE *fp; char *filename = "2.txt"; char str1[N]; char str2[N]; char kaigyo[] = "\n"; int i; int a=0; char fname[64]; printf("file:"); scanf("%s", fname);   ←ここで1.txtを入力するとします fp = fopen(fname, "r"); while(fgets(str1, N, fp) != NULL){ delkaigyo(str1, kaigyo); memset(str1, 0, N); fread(str1, 1, N-1, fp); if((fp = fopen(filename, "r")) == NULL){ fprintf(stderr, "%serror.\n", filename); exit(EXIT_FAILURE); } while(fgets(str2, N, fp) != NULL){ delkaigyo(str2,kaigyo); if(strstr(str1,str2)!=NULL){ a = 1; printf("%s\n", str1); break; } } if(a==0){ return 0; } fclose(fp); } return EXIT_SUCCESS; }

  • 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

  • コンパイルエラー

    Borlnd C++ compilerでコンパイルしたのですが、どうしてもエラーがでてしまいます。エラーは、不正な文字’’(0×8140)(関数 main) エラーE2206 文字' ' (0×8140)(関数 main) エラーE2206と二つ同じエラーがあると表示されます。本当に分からないので力を貸したください。お願いします。 /*読み込んだ二つの整数値の大きい方の値を求めて表示(条件演算子)*/ #include <stdio.h> int main(void) { int n1, n2, max; puts("二つの整数を入力してください。");   printf("整数1 : "); scanf("%d", &n1); printf("整数2 : "); scanf("%d", &n2); max = (n1 > n2) ? n1 : n2; printf("大きい方の値は%dです。\n", max); return 0;

このQ&Aのポイント
  • 【マルチファンクションプリンタ】に関するトラブルや相談内容、使用環境、接続方法、ソフト・アプリの情報、電話回線の種類についてお教えください。
  • お困りの内容、トラブルの経緯、試したこと、エラーメッセージなど、【マルチファンクションプリンタ】に関する全ての情報を教えてください。
  • パソコンやスマートフォンのOS、接続方法、関連するソフト・アプリ、電話回線の種類など、【マルチファンクションプリンタ】に関する環境情報をお知らせください。
回答を見る