C言語の領域確保について

このQ&Aのポイント
  • C言語を始めたばかりのものです。配列を計算させようとするプログラムで、配列の領域確保がうまくいかない問題が発生しています。領域確保の方法や失敗の原因について教えてください。
  • また、csvからの値の取得やfgetsのライン数の値についても正しい方法を知りたいです。
  • 最終的には500行2048列の計算を行う必要があるので、効率的な方法についてもアドバイスが欲しいです。
回答を見る
  • ベストアンサー

C言語の領域確保について

C言語を始めたばかりのものです。 配列を計算させようと下のようなプログラムを作り、一応動作はするのですが、配列の領域確保がいまいちわかりません。配列はcsvから値をとっています。確保する領域は、代入する値の数でいいので、buff[8×64]、とかarv[4×32]でいいと思い、それより少し大きな値くらいで実行すると失敗してしまいます。  自分の理解の仕方が間違っているとは思っているのですが、(char *)malloc(M*N*sizeof(char))でやっても失敗しました。どうすればよいかお教え願います。ちなみに、csvの値は0.000852354710804709のように桁が半端ないです。  またfgetsのライン数の値も正しくするにはどうすればよいのでしょうか。できたらmallocを使えたらよいと思っています。 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #define N 8 //8行 #define M 64 //64列 int main() { char *fname = "test.csv";//8行64列 char *ffname = "tk.csv";//4行32列 FILE *IN1, *IN2, *OUT1, *OUT2; char buff[100000];//←問題の部分 char *pbuff; char arv[400];//←問題の部分 char *parv; double a[N][M+30], b[N][M], c[N][M], w[4][32]; int i, j, x; double m, n; int count=0; if((IN1 = fopen(fname, "r")) == NULL){ printf("can't open the %s", fname); return 0; } if((IN2 = fopen(ffname, "r")) == NULL){ printf("can't open the %s", ffname); return 0; } i=j=0;//配列の取得 while(fgets(buff, 100000, IN1) != NULL){ pbuff = buff; while((pbuff = strtok(pbuff, ",\n")) != NULL){ a[i][j++] = strtod(pbuff, NULL); pbuff = NULL; } i++; j=0; } i=j=0;//配列の取得 while(fgets(arv, 400, IN2) != NULL){ parv = arv; while((parv = strtok(parv, ",\n")) != NULL){ w[i][j++] = strtod(parv, NULL); parv = NULL; } i++; j=0; }             :             :             : このプログラムでも計算はできるのでいいのですが、最終的には500行2048列の計算をしないといけないので、いっそう数字が膨大となるために質問させていただきました。Visual Stdio 2010 c/c++ 使ってます。

noname#244557
noname#244557

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

  • ベストアンサー
  • chie65535
  • ベストアンサー率43% (8524/19375)
回答No.2

buffもarvも「ファイルの中で、最も長い行の文字数+α」で良い。 例えば、最長の行が「先頭から改行まで、トータルで5329文字、改行も入れると5330文字」と言うのであれば、+αして、5400バイトあれば問題無い。 >最終的には500行2048列の計算をしないといけないので 2048列で、1つの列にある「数値」は「最大桁数」が決まっている筈。 例えば、最大桁数が50桁なら、1行の最大文字数は「50×2048+2047+1=104448」と計算できる(「2047」は「,」の分、「1」は改行の分) 安全の為に「+α」して、104500バイトのbuffを用意すれば良い。 arvの最大必要バイト数も、同じように計算が可能。 >できたらmallocを使えたらよいと思っています。 char buff[100000];//←問題の部分 を char *buff; buff=malloc(100000); if (buff == NULL) { abort(); return; } に変えるだけだ。 もし、計算で求めた「1行の最大バイト数+α」が「104500」になったのなら、100000を104500に変えれば良い。

noname#244557
質問者

お礼

なるほど,桁数も考慮して確保する領域を決めるのですね.csvに関する疑問が多く困っていたのですが,これでかなり解消されました.丁寧に説明していただきありがとうございます!

その他の回答 (1)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

とりあえず, プログラムには動作を説明するコメントを入れてください. もちろん自分だけで使うプログラムならコメントを書こうと書くまいと私の知ったことではありませんが, 他人に見せるプログラムにはある程度の処理のまとまりごとに「そこで何をしているのか (あるいは何をしたいのか)」をコメントで入れてください. 特にここでは他人に「見てもらう」プログラムなのだから, そのくらいの手間は惜しまないでください. あと, 「失敗する」というのが何を意味するのかが分かりません. あなたのいう「失敗」とは, 具体的にはどういうことなのですか? 「fgetsのライン数の値も正しくするにはどうすればよいのでしょうか」は意味不明. 「fgets のライン数の値」ってなんですか?

noname#244557
質問者

お礼

説明不足で失礼しました.失敗に関しては,VisualStdioごと停止していました.またfgetsは1ライン(行)で文字列を受け取るバイト数のことですが,chie65535さんのおかげで解決しました.回答ありがとうございます.

関連するQ&A

  • C言語のオーバーフローについて

    csvからデータを読み取り、計算させるプログラムで、行が多くなると「StuckOverFlowReception」と表示されます。静的に領域を確保していることに原因があるような気がするのですが、どこがオーバーフローしているのか、どう直せばよいのかがわかりません。改善のご指摘をお願いします。 VisualStudio2010をwindows7で使用しています。プログラム初心者なので、かなりみにくいかもしれません。すいません。ちなみに15行ぐらいにするとオバーフローと表示されます。 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #define N 20//行数の定義 #define M 2048//列数の定義 int main() { char *fname = "ttt.csv"; //読み取り用ファイル char *ffname = "tk.csv"; //読み取り用ファイル FILE *IN1, *IN2, *OUT1, *OUT2; char buff[30000]; //配列を静的に確保(桁が大きいので、大きくとっています) char *pbuff; //読み取ったデータを格納する用 char arv[600]; //ffnameの配列用 char *parv; //arv[]の格納用 double a[N][M+30], b[N][M], c[N][M], w[4][32]; //配列の領域を定義 int i, j, x; //for文の繰り返し用 double m, n; //計算結果の一時的な格納用 if((IN1 = fopen(fname, "r")) == NULL){  ////ファイルを開く↓ printf("can't open the %s", fname); return 0; } if((IN2 = fopen(ffname, "r")) == NULL){ printf("can't open the %s", ffname); return 0; } if((OUT1 = fopen("high wavelet.csv", "w")) == NULL){ printf("can't open the ha.csv"); return 0; } if((OUT2 = fopen("low wavelet.csv", "w")) == NULL){ printf("can't open the la.csv"); return 0; }                         ////ファイルを開く↑ i=j=0; //配列の取得↓ while(fgets(buff, 30000, IN1) != NULL){ //csvデータ1行読み込みの繰り返し pbuff = buff; while((pbuff = strtok(pbuff, ",\n")) != NULL){ //pbuffのデータを区切る a[i][j++] = strtod(pbuff, NULL); //,をとばして配列に格納 pbuff = NULL; } i++; j=0; } i=j=0; //上の作業と同じ↓ while(fgets(arv, 600, IN2) != NULL){ parv = arv; while((parv = strtok(parv, ",\n")) != NULL){ w[i][j++] = strtod(parv, NULL); parv = NULL; } i++; j=0; }          ///ここまででcsvを配列に格納完了 x=0;                //計算上必要な       for(i=0; i<N; i++){         //作業をしてる for(j=0; j<30; j++){    //だけなので、ここは a[i][M+j] = a[i][j];//無視してください } } for(i=0; i<N; i++){        //ここから実際の計算 for(j=0; j<M; j++){  //計算長くてすいません m = (a[i][j]*w[0][0] + a[i][j+1]*w[0][1] + a[i][j+2]*w[0][2] + a[i][j+3]*w[0][3] + a[i][j+4]*w[0][4] + a[i][j+5]*w[0][5] + a[i][j+6]*w[0][6] + a[i][j+7]*w[0][7] + a[i][j+8]*w[0][8] + a[i][j+9]*w[0][9] + a[i][j+10]*w[0][10] + a[i][j+11]*w[0][11] + a[i][j+12]*w[0][12] + a[i][j+13]*w[0][13] + a[i][j+14]*w[0][14] + a[i][j+15]*w[0][15] + a[i][j+16]*w[0][16] + a[i][j+17]*w[0][17] + a[i][j+18]*w[0][18] + a[i][j+19]*w[0][19] + a[i][j+20]*w[0][20] + a[i][j+21]*w[0][21] + a[i][j+22]*w[0][22] + a[i][j+23]*w[0][23] + a[i][j+24]*w[0][24] + a[i][j+25]*w[0][25] + a[i][j+26]*w[0][26] + a[i][j+27]*w[0][27] + a[i][j+28]*w[0][28] + a[i][j+29]*w[0][29] + a[i][j+30]*w[0][30] + a[i][j+31]*w[0][31]); n = (a[i][j]*w[1][0] + a[i][j+1]*w[1][1] + a[i][j+2]*w[1][2] + a[i][j+3]*w[1][3] + a[i][j+4]*w[1][4] + a[i][j+5]*w[1][5] + a[i][j+6]*w[1][6] + a[i][j+7]*w[1][7] + a[i][j+8]*w[1][8] + a[i][j+9]*w[1][9] + a[i][j+10]*w[1][10] + a[i][j+11]*w[1][11] + a[i][j+12]*w[1][12] + a[i][j+13]*w[1][13] + a[i][j+14]*w[1][14] + a[i][j+15]*w[1][15] + a[i][j+16]*w[1][16] + a[i][j+17]*w[1][17] + a[i][j+18]*w[1][18] + a[i][j+19]*w[1][19] + a[i][j+20]*w[1][20] + a[i][j+21]*w[1][21] + a[i][j+22]*w[1][22] + a[i][j+23]*w[1][23] + a[i][j+24]*w[1][24] + a[i][j+25]*w[1][25] + a[i][j+26]*w[1][26] + a[i][j+27]*w[1][27] + a[i][j+28]*w[1][28] + a[i][j+29]*w[1][29] + a[i][j+30]*w[1][30] + a[i][j+31]*w[1][31]); b[i][x] = m; //配列×配列をしてm、nに一時的に格納し c[i][x] = n; //新たな配列に入れてます x++; j++; } x=0; } for(i=0; i<N; i++){       //ここから新たに得た配列をcsvに書き込んでいます for(j=0; j<(M/2); j++){ fprintf(OUT1, "%e", b[i][j]); fprintf(OUT2, "%e", c[i][j]); if(j==(M/2-1)){ fprintf(OUT1, "\n"); fprintf(OUT2, "\n"); }else{ fprintf(OUT1, ","); fprintf(OUT2, ","); } } } fclose(IN1); fclose(IN2); fclose(OUT1); fclose(OUT2); rewind(stdin); getchar(); return 0; }

  • C言語についてアドバイスをください。

    CSVファイルの内容をfreadで読み込み、strtokを使わずにbuffに格納した後、 buffから1文字ずつbuff2へコピーさせていって、コンマがきたら数字、 改行がきたら名前と判別して、自作関数に渡して表示させたいです。 CSVファイルの内容は 『11,名前1(改行) 15,名前2(改行) 18,名前3』 といった感じです。 ------------------------------------------------------- #define _CRT_SECURE_NO_DEPRECATE 1 #include <stdio.h> #include <string.h> #include <stdlib.h> #define NUM 256 struct kou { short nenrei; char namae[30]; }; void pri(struct kou *o) { printf("%d\n%s\n",o->nenrei,o->namae); } int main(void) { FILE *fp; // ファイルポインタ char buff1[NUM] = {0}; char buff2[NUM] = {0}; char *fname = "text1.csv"; // ファイル名を指定 short i = 0; int n = 0; struct kou p; fp = fopen(fname, "r"); if(fp == NULL) { printf("%sファイルをオープンできませんでした。\n",fname); } fread(buff, 1, NUM, fp); while(buff1[n] != NULL) { buff2[n] = buff1[n]; // buff2[0]からbuff1の中を一文字ずつコピーしていく。 if(buff2[n] == ',') // buff2に格納されていく中にコンマがきたら以下の作業を行う。 { i = (short)atoi(buff2); // char型からshort型への変換 p.nenrei = i; } if(buff2[n] == '\n') { strcpy(p.namae,buff2); // p.namaeにbuff2をコピー。 pri(&p); } n++; } fclose(fp); printf("ファイルをクローズしました。\n"); return 0; } ------------------------------------------------------- 今のままだと 『11 11,名前1 11 11,名前1 15,名前2』 という表示になってしまいます。 while 内で既に読み込んだ部分を読み込ませないよう(表示させないよう)にできたら良いと思うんですが、そういったやり方はあるのでしょうか? むしろやり方を変えたほうが良いでしょうか・・・。 まだC言語を学び始めて日が浅いので、色々間違っている部分もあると思いますが、 そういったことを含めてアドバイスをいただけたらと思います。 よろしくお願いします。

  • C言語について教えてください。

    数日前に「http://okwave.jp/qa4903738.html」で質問させてもらった者です。 前回、寝起きでボケてるうちに回答を締め切ってしまって、 回答してくださった方との対話ができていませんでした。 すみません。 今回は前回の指摘された部分を含めて回答を戴きたく投稿させてもらいます。 質問内容はほぼ変わりありません。 CSVファイルの内容をfreadで読み込み、strtokを使わずにbuffに格納した後、 buffから1文字ずつbuff2へコピーさせていって、コンマがきたら数字、 改行がきたら名前と判別して、自作関数に渡して表示させたいです。 あと、fgetsは使わないようにしたいです。 CSVファイルの内容は 『11,名前1(改行) 15,名前2(改行) 18,名前3』 といった感じです。 ----------------------------------------------- #define _CRT_SECURE_NO_DEPRECATE 1 #include <stdio.h> #include <string.h> #include <stdlib.h> #define NUM 256 struct kou { short nenrei; char namae[30]; }; void pri(struct kou o) { printf("%d\n%s\n",o.nenrei,o.namae); } int main(void) { FILE *fp; // ファイルポインタ char buff1[NUM] = {0}; char buff2[NUM] = {0}; char *fname = "text1.csv"; // ファイル名を指定 int n = 0; struct kou p; fp = fopen(fname, "r"); if(fp == NULL) { printf("%sファイルをオープンできませんでした。\n",fname); return 1; } fread(buff1, 1, NUM, fp); // ここでファイルの内容が全てbuffに入る。 // printf("%s\n",buff1); // buff1にファイルの内容が書き込まれているか確認する。 while((buff2[n] = buff1[n]) != NULL) // buff2[0]からbuff1の中が終わるまで一文字ずつコピーしていく。 { if(buff2[n] == ',') // buff2に格納されていく中にコンマがきたら以下の作業を行う。 { p.nenrei = atoi(buff2); // char型からshort型への変換し、p.iAgeに入れていく。 } if(buff2[n] == '\n') { strcpy(p.namae,buff2); // p.namaeにbuff2をコピー。 pri(&p); } n++; } fclose(fp); printf("ファイルをクローズしました。\n"); return 0; } ----------------------------------------------- 前回指摘されたwhileの条件式ですが、 まだchar型とポインタを比べてることになっているので正しくないんですよね? 正直、どうすればいいかわかりません。 あと、今のままでは名前3の後が改行ではないので表示されることないですよね・・・。 どうすれば表示されるようになるでしょうか。 これも前回言われましたが while内の1つ目のif文の所で、カンマを処理したので次に取り込むbuff2への書き込み位置の変更というのもわかりません。 カンマが来た時点でbuff2[n]のnは2になっているんですよね? ということはbuff2[3]からまた読み込めたらいいということですよね? 厚かましくも立て続けに質問してしまって申し訳ありませんが回答を戴けたらありがたく思います。 宜しくお願いします。

  • C言語 strtok

    失礼します。現在こちらでアドバイスを頂きfgetcを使用して配列に格納をすることができたのですが、CSVをカンマ区切りで格納したいのですが上手くいかず困っています。strtokを使用方法をドキュメントを読んでもうまく区切ったものを配列に入れる方法がわかりません 何卒よろしくお願いします。 ソースコード #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include<string.h> #define MAXITEM 1400 int split(char *str, const char *delim, char *outlist[]) { char *tk; int cnt = 0; tk = strtok(str, delim); while (tk != NULL && cnt < MAXITEM) { outlist[cnt++] = tk; tk = strtok(NULL, delim); } return cnt; } int main(void) { FILE *fp; char *fname = "testfile.csv"; char *tp; char *array[1400]; char *test[11][1400]; char c; int i = 0; int n,y; char *tp[1400]; fp = fopen(fname, "r"); if (fp == NULL) { printf("%sファイルが開けません¥n", fname); return -1; } while ((c = fgetc(fp)) != EOF) { array[i] = (char)c; i++; } tp = strtok(array, ","); puts(*tp); while (tp != NULL) { tp = strtok(NULL, ","); if (tp != NULL)puts(tp); } for (n = 0; n < 11; n++) { for (y = 0; y < 1400; y++) { test[n][y] = tp[y]; printf("%c", test[n][y]); } } fclose(fp); return 0; }

  • Borland C CSVファイル読み込み

    CSVファイルを読み込み、読み込んだ値で計算を行うプログラムを作っています。 ・環境はWindows VISTA UltimateでBorland C++ Compiler 5.5  ・CSVファイルのデータの形式は 1,4532 4,2131 6,4301 . . ・データ数は決まっていて今のところ全部で12個 そして以下のようにCSVの読み込みプログラムを試しに組んだ所、実行時エラーがでました。 #include <stdio.h> #include <stdlib.h> #include <string.h> void main(void) { int AN[11][1]; int i=0,j=0,c=0; char buff[1024], *tp; FILE *fp; /*配列初期化*/ for(i=0;i<11;i++) { for(j=0;j<2;j++) { AN[i][j]=0; } } fp=fopen("test1.csv","r"); if(fp==NULL) { /* オープン失敗 */ printf("ファイルがオープンできません\n"); exit(1); /* 強制終了 */ } while( fgets(buff, 1024 , fp) != NULL ) { tp=strtok(buff , ","); if (tp !=NULL) {AN[i][j] = atoi(tp);} printf("%d\n",AN[i][j]); tp = strtok(NULL , ","); if (tp !=NULL) {AN[i][j+1] = atoi(tp);} printf("%d\n",AN[i][j+1]); i++; } fclose(fp); } 実行するとファイルクローズの後、問題が発生したためプログラムを終了しましたと出ます。"AN[i][j]=atoi(tp)"の配列部分を単純に変数にするとこのようなエラーは出ないのですが。 なぜエラーが出るのか、どなたかご教授願います。

  • ファイルの読み込みとメモリ確保について。

    ファイルから文字を読み込んで それを配列に入れて辞書順にソートさせようとしています。 それで、ソート以前の問題なのですが、ファイルから文字列を読み込んで配列にいれようとするのですが、 buffを動的にメモリ確保してその配列に入れたいと考えているのですが、なぜか入ってくれません。 whileでファイルの終わりがくるまで一行ずつ読み込んで それをsに入れていき、sをbuff[]の配列に順番にいれていこうとしているのですが・・・。 ファイルは aaaa aabc dda wer zie ced sdfe be など適当な文字の並びです。 malloc関数で動的に確保したメモリはその後普通の配列と同様に使えるのではなかったのでしょうか? なので普通にbuff[i]=s;といった処理で入れれると思ったのですが。 ファイルは一行の長さの最大が100で 行数が4000行あると仮定しています。 今は小さいファイルでテストしていますが。 以下ソースです。 #include <stdio.h> #include <stdlib.h> #define MAX_SIZE 100 #define MAX_LINE 4000 main() { FILE *fp; char *buff,s[MAX_SIZE]; int i; fp=fopen("words.txt","r"); buff=(char*)malloc(sizeof(char)*MAX_LINE); i=0; while(fgets(s,MAX_SIZE-1,fp)!=NULL){ buff[i]=s; printf("%s",buff[i]); i++; } fclose(fp); } とりあえずファイルの内容を配列に入れないとソートできないので、配列に全て入れてしまいたいと考えています。 間違いがどこにあるのか指摘よろしくおねがいします。m(-_-)m

  • Cで2次元配列にCSVファイルを格納するには?

    ~.csvというファイルがあって、ファイルの中身は256*256のある数字の2次元配列です。 このファイルを読み込んで、2次元配列に格納したいのですが、どのようなソースを書けばいいのでしょうか? プログラミングをちゃんと勉強してこなかったために苦戦しています。 #include <stdio.h> #include <stdlib.h> int main(int argc,char *argv[]){ FILE *fi; char I[256]; char J[256]; if((fi=fopen("ch.csv","r"))==NULL){//csvもこのような記述でよみこむことができるのか? printf("ファイルオープンエラー\n"); exit(1); } while(fgets(J,256,fi) != NULL) { これより先が全く書けていない状態です。 ここまでもこのソースで大丈夫でしょうか? かなり基本的なことだと思いますが、よろしくお願いします。

  • 型によらないCSVファイルの読み込みC言語プログラ

    あらかじめ型のわかっているN行*M列のエクセルデータをCSV形式にし、 読み込むプログラムを作成しました。 そのプログラムを下に示します #include <stdio.h> #include <stdlib.h> #include <string.h> /* 確保するデータ保存領域の大きさ(N行×M列) */ #define N 23 #define M 6 /* データの区切り文字 */ #define SEP_DATA ',' int csv_read(char filename[], double csv[N][M]) { /* ファイルオープン */ FILE *fp; if( (fp = fopen(filename, "r")) == NULL ) { printf(" file open error!!\n"); return -1; } /* 1行毎に読み出し */ char line[256], *ptr; int i, j, k; i=0; while (fgets(line, 256, fp) != NULL) { printf("*%s", line); ptr = line; j=0; do{ /* line[j]から次のタブ文字までを数値に変換 */ csv[i][j] = atof(ptr); /* 次のタブ文字の位置を探す */ ptr = strchr(ptr, SEP_DATA); /* タブ文字の次の文字を示す */ if (ptr!=NULL) { ptr++; } j++; }while(ptr!=NULL && j<M); i++; } /* ファイルクローズ */ fclose(fp); return 0; } int main(int argv, char *argc[]) { char filename[256]; if( argv > 1){ strcpy(filename, argc[1]); } else { printf("Please Input Filename:"); scanf("%s", filename); } /* データ保存用の領域を確保 */ double (*csvdata)[M]; csvdata = (double(*)[M])malloc(sizeof(double[M]) * N); //malloc(sizeof(*csvdata) * N); if ( csvdata == NULL ){ return -1; } int i,j; /* 配列の初期化 */ for( i=0; i<N; i++) { for( j=0; j<M; j++) { csvdata[i][j] = 0.0; } } /* CSVデータの読み込み */ if( csv_read(filename, csvdata) < 0 ) { return -1; } /* 配列の出力 */ for( i=0; i<N; i++) { printf("%lf", csvdata[i][0]); for( j=1; j<M; j++) { printf("\t%lf", csvdata[i][j]); } printf("\n"); } free(csvdata); csvdata = NULL; return 0; } これをNとMがどんな値であれ読み込めるようにするにはどうすれいいでしょうか

  • 漢字を配列に入れたいのですが

    漢字を配列に入れたいのですが、うまくいきません。 3列、60行のcsvファイルを読み込んで配列に入れようをしているのですが、1列目、2列目、3列目にある漢字をそれぞれ配列に入れようとしているのですが、出力するとうまくいかないんです。誰か教えてください。 #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXBUFFSIZE 256 #define MAXWORDS 15 int split(char* words[], int length, char* split_ch,char* str){ int i,j; for(i=0;i<length;i++){ if((words[i] = strtok(str,split_ch))==NULL)break; str=NULL; } return(i); } int main(int argc, char* argv[]){ if(argc !=2){ printf("入力エラー"); return(0); } FILE *fp; char *ll, *words[MAXWORDS], ch, buff[MAXBUFFSIZE]; int i,j; unsigned int data1[60], data2[60], data3[60]; if((fp =fopen(argv[1],"r"))==NULL){ printf("ファイルが開けません。\n"); } j=0; ll= fgets(buff,MAXBUFFSIZE,fp); while((ll= fgets(buff,MAXBUFFSIZE,fp)) != NULL){ split(words, MAXWORDS, ",",ll); data1[j] = words[0]; data2[j] = words[1]; data3[j] = words[2]; j++; } printf("%s\n%s\n%s\n", data1,data2,data3); }

  • C言語 ファイル内のデータと入力したデータの重複

    テキストファイルを読み込み、入力したデータとの重複がないかどうかを調べたいのですが、 わからない点があるため、質問させていただきます。 -------------------------------------------------------- #include <stdio.h> #include <stdlib.h> #include <string.h> int main() {    FILE *fp;    char datafile[];= "sample.txt";    char buff[512]; //読み込んだ1行分のデータを格納    char *data[1000]; //読み込んだデータを格納    int data_c = 0; //データの数    char str[256]; //入力された文字列を格納    int i;    int check; //重複チェック         (中略)    //ファイルを1行ずつ読み込み、その長さのメモリを確保し、値をコピー    while(fgets(buff, sizeof buff, fp) != NULL) {      data[data_c] = (char*)malloc(strlen(buff) + 1);      strcpy(data[data_c++], buff);    }         (中略)    //文字列を入力    fgets(str, 256, stdin);    check = 0;    //すでにあるデータと入力したデータの重複を調べる    for(i=0; i<data_c; i++) {      if(strcmp(data[i], str) == 0) {      check = 1;      break;      }    }         (中略) -------------------------------------------------------- 例えば読み込むファイルに5行書かれていた場合、 data[0]からdata[4]に確保したメモリの先頭アドレスが格納されますよね? ということはdata_cの値は4となるのですが、 その後のファイルデータと入力したデータの重複を調べるところで、 for(i=0; i<data_c; i++) となっており、data[0]からdata[3]までの4行分しか調べられないことになります。 なぜ、i<=data_cではなく、i<data_cとなっているのか、わかりましたら教えていただけますでしょうか。

専門家に質問してみよう