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

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

ただいまの
回答率

91.25%

  • C

    2682questions

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

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

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 71

sanchu52

score 74

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

// 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
$
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

if (buff == NULL)

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

if (ptr == NULL)

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

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


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

    if (stat(file, &statBuf) == 0) { // <=== braceが必要
        // ファイルfileからファイル情報を取得し、
        // stat構造体変数statBuf)に格納する。

        size = (int)(statBuf.st_size);        // サイズを取得
        printf("size: %d(バイト)\n",size);    // 表示

        return statBuf.st_size;
    }  // <=== braceが必要
    return -1L;
}

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

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/03 20:41

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

    キャンセル

  • 2018/01/03 21:02

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

    キャンセル

  • 2018/01/03 21:22

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

    キャンセル

  • 2018/01/03 22:25

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

    キャンセル

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

ただいまの回答率

91.25%

関連した質問

同じタグがついた質問を見る

  • C

    2682questions

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

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