質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

1回答

377閲覧

テキストファイル探して表示するプログラムで最後のデータがダブって表示される

退会済みユーザー

退会済みユーザー

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2018/01/03 10:53

編集2018/01/03 12:21

テキストファイル探して表示するプログラムで最後のデータがダブって表示されるので
、どこがわるいのか分からないので教えてください。

// delete_seek5.c #include <stdio.h> #include <stdlib.h> #include <sys\stat.h> //ファイルサイズを取得する long getFileSize(char *file) { struct stat statBuf; int size; if (stat(file, &statBuf) == 0) // ファイルfileからファイル情報を取得し、 // stat構造体変数statBuf)に格納する。 size = (int)(statBuf.st_size); // サイズを取得 printf("size: %d(バイト)\n",size); // 表示 return statBuf.st_size; // off_t st_size; // 全体のサイズ (バイト単位) return -1L; } int main() { FILE *fp; char *ptr; char *file = "data_tel.txt"; long size; char buff[100+1]; fp = fopen(file, "r"); if (fp == NULL){ printf("ファイルオープンエラー\n"); return -1; } //write(file); size = getFileSize(file);   if (size == -1){ printf("ファイルサイズの取得に失敗しました\n"); return -1; } printf("printf1%sのサイズ: %ld\n", file, size); //mallocでメモリを確保する ptr = ( char * )malloc(size); if (ptr == NULL) { printf("malloc()に失敗しました。\n"); return -1; } printf("確保したメモリブロックのアドレス: %p\n\n", ptr); while(ptr){ ptr= fgets(buff, 100, fp); // fgetsが返すbuffの先頭アドレスをptrに代入する。 if (buff == NULL){ printf("読み込みデータなし\n"); }else{ printf("%s", buff); // printf()関数で読み込んだ内容を表示します。 // fgets()関数でbuffに読み込まれるのはfileの改行も // 読み込むので\nとしなくても、改行される。 } } printf("fseek:%d\n", fseek(fp, 0, SEEK_SET)); // SEEK_SET:ファイルの先頭から // fseek()関数で読み込み位置をファイルの先頭から // 0バイト目に戻します。 fclose(fp); } 実行結果は以下になります。 naka@naka ~/kadai/kadai9-8 $ gcc -o delete_seek5 delete_seek5.c -Wall naka@naka ~/kadai/kadai9-8 $ delete_seek5 size: 120(バイト) printf1data_tel.txtのサイズ: 120 確保したメモリブロックのアドレス: 02B92AF8 naka ,090-7777 kiyoko ,090-9999 satou ,090-3214 kinosita ,090-8679 yamada ,090-4325 itou ,080-6354 読み込みデータなし fseek:0 naka@naka ~/kadai/kadai9-8 $

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

if (buff == NULL)

この判定文がおかしいですね。fgetsでEOFに到達したかどうかを判定するなら

if (ptr == NULL)

としなければなりません。buffは配列ですからこのif文が成立することはあり得ないわけです。EOFに到達したかどうかはwhile文の条件でチェックされてはいますが、上記if文でEOFかどうかの判定をし損ねているため、EOFに達しているにもかかわらずbuffの中身を表示しており、それが本件の現象の原因です。

本来EOFに達した際に「読み込みデータなし」と表示されるように意図していたと思いますが、それが表示されずにプログラムが終了した点について気付けたらご自分でもわかったかも知れませんね。


余談ですが、getFileSize関数のif文のbraceが抜けているように思います。インデンテーションからいえば以下のようにするつもりだったのだと思います。

C

1 if (stat(file, &statBuf) == 0) { // <=== braceが必要 2 // ファイルfileからファイル情報を取得し、 3 // stat構造体変数statBuf)に格納する。 4 5 size = (int)(statBuf.st_size); // サイズを取得 6 printf("size: %d(バイト)\n",size); // 表示 7 8 return statBuf.st_size; 9 } // <=== braceが必要 10 return -1L; 11}

またせっかくgetFileSizeでエラーチェックをやっていますが、呼び出し元のmain関数の中で結果が-1かどうかお構いなしに先に進めています。main関数でのエラーチェック漏れではないですか?

投稿2018/01/03 11:09

編集2018/01/03 11:14
KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/01/03 11:41

ありがとうございます。朝からやっていました。よたよたしながらコード書いています。getFileSizeのエラーチェックをmain関数で生かすにはどのように すればいいですか。厚かましいですが具体的に教えていただきませんか。 このコードを書くのに、getFileSize()、fgets(),fseek(),malloc()などすべて復習しながらです。
KSwordOfHaste

2018/01/03 12:02

戻り値が0以上なら正常、負ならエラーと考えればよいと思います。関数を書いたご本人がわかるはずでは?
退会済みユーザー

退会済みユーザー

2018/01/03 12:22

main関数のgetFileSize()の後に、エラー処理を追加しました。これでいいでしょうか。
KSwordOfHaste

2018/01/03 13:25

特に問題ないと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問