• ベストアンサー

ファイルからの全文読み込み

ファイルから全文読み込むにはどのようにしたらよいのでしょう? ・1行あたり最大100文字まで ・何行あるか不明 ・すべて半角英数字 ・途中に半角スペースあり 全文読み出し、配列に取っておきたいと思いますが、 具体的にどうしたらよいのかわかりません。 fgetsですと最後の1行しか取れませんし・・

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

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

改行を\0に置き換えながらその次のアドレスをchar*に入れていく これは char** line = malloc(sizeof(char*) * line_count); line[0] = strtok( buf, "\n" ); for (i = 1; i < line_count; i++) { line[i] = strtok( NULL, "\n" ); } でできそうですね bufはファイル全部を読み込んだポインタでline_countはbufをサーチして数えた行数(\nの数)です。 bufの最後には0が必要ですのでメモリ確保時に1バイト余分に確保して最後に0を代入すればいいでしょう。

その他の回答 (4)

回答No.5

ファイルからfgetsで1行ずつ読みながらリストに追加していく方法がシンプルではないでしょうか。 こんな感じ?(サンプルですので動作保証しません) /* ファイルから読んだ文字列をリストに入れる */ #include <stdio.h> #include <stdlib.h> #include <string.h> struct node {  struct node* next; /* 次のデータへのポインタ */  char *record; /* データ内容 */ }; /* リストの最後にデータを付加する */ void addlist(struct node *p, char *s) {  struct node *pp;  while (p->next != NULL) p=p->next; /* 最後のノードを探す */  pp=(struct node*)malloc(sizeof(struct node)); /* 新しいノード */  if (pp==NULL) {   printf("pp malloc error\n"); return;  }  pp->record=(char*)malloc(strlen(s)+1); /* 新しいデータ */  if (pp->record==NULL) {   printf("record malloc error\n"); return;  }  strcpy(pp->record, s); /* データの内容をコピー */  pp->next=p->next; p->next=pp; /* リストに挿入 */ } /* リストの内容を表示 */ void printlist(struct node *p) {  while ((p=p->next)!=NULL) {   printf("%s",p->record);  } } /* リストを全部消す */ void rmlist(struct node *p) {  struct node *pp=p->next;  p->next=NULL; /* rootはmallocしてないのでfreeしないでNULL入れる */  while (pp!=NULL) {   p=pp;   pp=pp->next;   free(p->record); free(p); /* mallocした領域を開放 */  } } int main(int argc, char **argv) {  struct node root={NULL,""};  FILE *fp;  char buf[256];  /* コマンドラインからファイル名取得して開く */  if (argc!=2) return -1;  if ((fp=fopen(argv[1],"r"))==NULL) {   printf("%s open error\n",argv[1]); return -1;  }  /* 全文を読みながらリストに追加 */  while(fgets(buf, sizeof(buf),fp)!=NULL) {   addlist(&root,buf);  }  /* ファイルを閉じる */  fclose(fp);  /* リストを表示 */  printlist(&root);  /* リストを消す */  rmlist(&root);    return 0; }

noname#88772
noname#88772
回答No.3

こんにちは。 linux系だとfstatでファイルサイズが取れますが環境が解らないので stdio.h の範囲内で、こんな感じでどうでしょうか? /* ファイルオープン (fopen) */ /* ファイル最後に移動 (fseek) */ /* ファイルサイズを取得 (ftell) */ /* ファイル先頭に戻す (fseek) */ /* ファイルサイズ分の配列を確保 */ /* ファイル読み込み (fread) */ /* ファイルクローズ (fclose) */ ご参考までに。

  • rub_oil
  • ベストアンサー率14% (3/21)
回答No.2

>fgetsですと最後の1行しか取れませんし・・ 間違い。 ひょっとしたらそんな仕様のコンパイラもあるのかもしれませんが 通常、1バイト目から取りにいきます。 最悪、fseekで強制的に読み取り位置を変えてやればいいかと。 fgetsは指定したバイト数だけ引っ張ってきます。 ひょっとして、リードバッファをずっと同じものを使っているから ループから抜けたときに最終行を保持してるのではないでしょうか?

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

ファイルサイズを取得してその分のメモリを確保して全部読み込む 改行の数を数えてその数のchar*を確保 改行を\0に置き換えながらその次のアドレスをchar*に入れていく とか

hardtechno
質問者

補足

そんなことができそうだな~というのは浮かんではいるのですが、 具体的にどのようにコードを組んだらよいのかを悩んでます。

関連するQ&A

  • ファイルからサイズ不明の行データを読み込む場合

    C言語でファイルからデータを読み込み、そのデータを編集しファイルに出力する というプログラムを作成しています。 ファイルデータはfgetsを使用し、読み込んでいます。 そこでお聞きしたいのですが現在、ファイル1行の最大サイズが不明のためfgetsで設定する 文字サイズをかなり大きくとってあります。 (とりあえず確認できた最大サイズが4000バイトだったので保険もかねて20000バイトを  設定しています) やはり文字サイズを大きくすると性能等に影響があるのでしょうか? また、ファイル1行の最大サイズが不明の場合、通常どのようにファイルを読み込むべき なのでしょうか? ご回答の方よろしくお願いします。

  • FILE構造体のファイルポインタについて質問です。

    FILE構造体のファイルポインタについて質問です。 Microsoft VC++を使っています。 テキストファイル(1行の連続して文字が連なっている。)のn文字目からの文字を読み取る場合、fgetsでn-1文字目まで読み取ってから、fgetsでn文字目から読み取ればできるのですが、ファイルポインタを使用した場合について教えてください。 FILE *fp; fp = fopen("a.txt","r"); と宣言すると、fp->_ptrがファイルポインタになります。 この段階でfp->_ptrは0で、値を読み込みとエラーになります。(ファイルの実行が停止) fgets()で何文字でもいいから読み込むと、fp->_ptrにアドレスが読み込まれます。 fp->_ptrに加算してn-1文字目まで動かして、fgetsで文字を読み込めば読み込めるのですが、 ファイルの残りの文字数よりも読み込む文字数が大きい場合、その差分だけへ(アスキーコード205) が読み込まれます。 詳しく説明すると、テキストファイルにn文字目からabcdeという5文字があるとします。 n文字目から10文字読み込んだ場合、配列に格納される文字がabcdeヘヘヘヘヘになってしまいます。 へ(アスキーコード205)の数は最大でfp->ptrに加算した値となっています。 質問としましては (1)fp->ptrにアドレスが書き込まれるのはどのタイミングなのでしょうか? (2)なぜへ(アスキーコード205)が格納されてしまうのか? 分かる方、是非ご教授をよろしくお願いします。

  • ファイルから読み取った「行の長さ」は・・?

    すみません。 while (fgets(buff, 256, pFile) != NULL) { ~~~ } として1行ずつファイルを読み込み、その中で1文字ずつ処理する為に 必要なforループのループ回数を得たいのですが・・ char buff[256]; // 先に確保した配列を、fgetsした後に int buff_length = sizeof(buff) /sizeof(buff[0]); // 長さを得ようとする こうすると確保したサイズ256が返ってきてしまい困っています。(当然かもですが・・ ファイルの1行の長さを毎回取得する方法は無いでしょうか?

  • 秀丸エディタで「-」や「ー」を文字の後に追加したい。

    秀丸エディタを使って「-」や「ー」などの文字を、英数字の行の後に追加するにはどのようにすればいいのでしょうか? 例えば、「-」や「ー」などの記号を英数字の後ろに追加したい場合、 1121 1121 などを 1121ー(全角スペース) 1121-(半角スペース) のようにしたいです。 よろしくお願いします。

  • 秀丸エディタで「-」や「ー」を文字の前に追加したい。

    秀丸エディタを使って「-」や「ー」などの文字を、英数字の行の前に追加するにはどのようにすればいいのでしょうか? 例えば、「-」や「ー」などの記号を英数字の前に追加したい場合、 1121 1121 などを ー1121(全角スペース) -1121(半角スペース) のようにしたいです。 よろしくお願いします。

  • ファイル読み込み EOF 判定

    数字の羅列した単純なテキストファイルを読み込ませたいのですが、 以下のようにすると、途中で改行などで一行あけた場合、そこで読むのを ストップしてしまいます。 if (fgets(buf, sizeof(buf), fp) == NULL) { 改行にくじけることなく、ファイルの最後まで読み込ませるにはどうしたら いいのでしょうか。 ちなみに、以下のようにやると、   while(getc(fp) != EOF){ こんどは改行をものともせず、ファイルのお終いまで読んでくれるのですが、 2バイト文字(頭一文字が化ける)、のっけ一行目に数値(10桁)を置くと 一文字かけて9桁になってしまいます。 2行目以降はちゃんと10桁です。(一行目に改行をいれて、2行目以降に書くと大丈夫のようです。変) 簡単なようで、つまってます。どうかよろしくお願いします。

  • 最終行をファイルを開かずにカットする方法はありますか?

    UNIXのviでファイルを開くと最終行が不完全といわれてしまいます。最後に半角スペースと変な文字が入っているようです。 viエディタのコマンドで、DDを押し最終行を手動でカットすると直るのですが、 Cやシェルなどで最終行をカットする方法はありますでしょうか?

  • シェルスクリプト(bash)によるファイルの編集

    シェルスクリプト(bash)によるファイルの編集についてのご相談です。 私にあまりスクリプトの知識がないので申し訳ございませんが、 どなたかお知恵を拝借させてください。 よろしくお願いします。 【条件】 ・以下のような文字列を含むファイルが複数あるとします。 ・そして、その文字列は、ファイル内の不特定の行に存在します。 ※[半角スペース]、[タブ]は実際には便宜上記載していますが、実際は 本当の半角スペース、タブが入ります。 AAA[半角スペース]BBB AAA[半角スペース]CCC AAA[タブ]BBB AAA[タブ]CCC 【やりたいこと】 このとき、 AAA[半角スペース]BBB および AAA[タブ]BBB の行の下に、それぞれ、 AAA[半角スペース]DDD  と   AAA[タブ]DDD を挿入したいのですが、これをスクリプト(コマンド)でどのように行えば よいのかわからずに困っています。

  • txtファイルの読込み時に1033文字を超えると

    txtファイルをfopen_s関数にモード"r"で読み込んでいます。 それをwhile (fgets(~~) != NULL) { ~ } で 1行ずつ読み込んでいるのですが、 この時1行の文字数が半角1033文字を超えていると 1034文字目からが「2行目扱い」になり 予期せぬ困った挙動を起こしてしまいます。 (Windowsのメモ帳では1035文字目から無理矢理改行表示されますが) なぜこの様な事が起こるのでしょうか? どうやって回避するのが一般的なのか教えて頂けますと幸いです。 ※OS:WindowsXP  コンパイラ:Visual C++2008 EE

  • 半角/全角の変換方法

    Excelで1つのセルの中に文章が入力されたデータがあります。 1行に対して1つの文章(A1に1つ、B1に1つという感じです)で 約2万行あり、1つの文章の長さは50文字~8000文字と様々です。 その文章の中には英数字も含まれているのですが その英数字が半角であったり、全角であったりと統一されておらず 不都合が出ておりますので、英数字は全て半角へ変換したいのですが 文字数が多すぎる為か、ASC関数ではエラーが表示(#VALUE!)される 行がいくつもあり困っております。 何かよい方法はないものでしょうか?

専門家に質問してみよう