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

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

ただいまの
回答率

90.52%

  • C

    3687questions

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

C言語のファイル出力が上手くいかない

解決済

回答 3

投稿

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

vn2731vn

score 3

C言語のfscanf, fprintf関数を使用してtxtファイルの内容を読み込んで、別のテキストファイルに書き込むプログラムを作成しています。
ソースコードと読み込むtxtファイルの内容は以下の通りです。

#include<stdio.h>
#include<stdlib.h>
#define STRLEN 100

int main(void){

    FILE *infp, *in_fp, *out_fp1, *out_fp2;
    char name[STRLEN];
    char gender[STRLEN];
    int age = 0;
    int count = 0;
    double ave = 0.00;

    infp = fopen("meibo.txt", "r");

    if(infp == NULL){
        fprintf(stderr, "Error : File is not open:errno:%d\n", errno);
        exit(1);
    }

    while(fscanf(infp, "%s%d%s",name, &age, gender) != EOF){
        count ++;
        ave += age;
    }
    ave = (double)ave / count;
    fclose(infp);

    in_fp = fopen("meibo.txt", "r");
    out_fp1 = fopen("meibo_h.txt", "w+");
    out_fp2 = fopen("meibo_l.txt", "w");
    if(in_fp == NULL || out_fp1 == NULL || out_fp2 == NULL){
        fprintf(stderr, "Error : File is not open:errno:%d\n", errno);
        exit(1);
    }
    while(fscanf(in_fp, "%s%d%s",name, &age, gender) != EOF){
        printf("%s %d %s\n",name, age, gender); //・・・①
        if(age >= ave){
            int result_h = fprintf(out_fp1, "%s  %d\n", name, age);
            printf("result=%d\n", result_h); //・・・②
        }else{
            int result_l = fprintf(out_fp2, "%s  %d\n", name, age);
            printf("result=%d\n", result_l); //・・・③
        }
    }
    printf("*****結果*****\n");
    printf("人数:%d人 平均年齢:%.2f才\n", count, ave);
    printf("-----平均以上-----\n");
    while(fscanf(out_fp1, "%s%d%s", name, &age, gender) != EOF){
        printf("%d\n", name); //・・・④
    }
    printf("**************\n");

    fclose(in_fp);
    fclose(out_fp1);
    fclose(out_fp2);

    return 0;
}


-------meibo.txt start--------
Yamada 20 man
Satou 60 woman
Suzuki 28 man
Tanaka 56 man
Aoki 44 woman
Saitou 25 man
Kobayashi 45 man
Hashimoto 53 woman
Yamaguchi 34 woman
-------meibo.txt end--------

①のprint文では読み込んだ名前、年齢、性別の情報が表示され
②,③のprint文では正の値が表示され、特にエラーは無いように思います。
しかし、書き込み先のtxtファイルであるmeibo_h.txtとmeibo_l.txtは真っ新な状態のままです。
最終的にmeibo_h.txtの内容を読み込み④で表示したいのですが
meibo_h.txtが空なので、当然表示されません。

何が問題なのか、どなたかご教示をよろしくお願いいたします。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 3

checkベストアンサー

+1

ファイルが別フォルダに生成されてるってことはないでしょうか。
書き込み先のファイルを削除して実行し直しても結果は同じでしょうか

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/07/03 17:07

    回答ありがとうございます。
    生成していたmeibo_h.txtとmeibo_l.txtを一旦消して、再度実行してみました。
    再びmeibo_h.txtとmeibo_l.txtが同じ場所に生成しましたが、中身は真っ新のままです。

    キャンセル

  • 2018/07/03 17:15

    さいごの、
    > while(fscanf(out_fp1, "%s%d%s", name, &age, gender) != EOF){
    > printf("%d\n", name); //・・・④
    > }

    をコメントアウトして実行させてみたらどうなるでしょう

    キャンセル

  • 2018/07/03 17:17

    上記3行をコメントアウトして実行したところ、meibo_h.txtとmeibo_l.txtに中身が書き込まれました!!

    キャンセル

  • 2018/07/03 17:25

    この場合この行の前にすべてのファイルをcloseし、改めて読み出しオープンして内容のチェックを行うようにすればいいです

    また、scanf系の関数は、文字列の文字数チェックが行われないので、そこでオーバーフローが起きないか注意しないとダメですねー

    キャンセル

  • 2018/07/03 17:46

    その都度、fcloseし、改めてfopenすることで、問題が解決しました。
    数々のアドバイスありがとうございました。

    キャンセル

  • 2018/07/03 20:18

    プログラムが終了する前にファイルの中身を見ていたと言うことですか?

    キャンセル

  • 2018/07/04 10:29

    プログラムが終了する・・・fopen→fscanf or fprintf→fcloseの一連の処理が終了するという意味でしたらそうだと思います。

    キャンセル

  • 2018/07/04 10:35

    なんと。そんな人もいるんだ。今後、心しておきます。

    キャンセル

0

#include <errno.h>が欠けている以外は特に問題無さそうです。
実行の仕方、確認の仕方が悪いのではないでしょうか。
違うディレクトリを見ているとか。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/07/03 17:12

    回答ありがとうございます。
    #include <errno.h>を追加しました。
    学習用C言語開発環境というものを使用しています。
    プログラムを実行するとmeibo_h.txtとmeibo_l.txtが生成することはするので、ディレクトリは合っていると思います。

    キャンセル

0

自己解決した訳ではありませんが、いただいた回答を元に修正し、期待通り動作しているソースコードを記載します。

#include<stdio.h>
#include<stdlib.h>
#include <errno.h>
#define STRLEN 100

int main(void){

    FILE *infp, *in_fp, *out_fp1, *out_fp2, *in__fp;
    char name[STRLEN];
    char gender[STRLEN];
    int age = 0;
    int count = 0;
    double ave = 0.00;

    infp = fopen("meibo.txt", "r");

    if(infp == NULL){
        fprintf(stderr, "Error : File is not open:errno:%d\n", errno);
        exit(1);
    }

    while(fscanf(infp, "%s%d%s",name, &age, gender) != EOF){
        count ++;
        ave += age;
    }
    ave = (double)ave / count;

    fclose(infp);

    in_fp = fopen("meibo.txt", "r");
    out_fp1 = fopen("meibo_h.txt", "w+");
    out_fp2 = fopen("meibo_l.txt", "w");

    if(in_fp == NULL || out_fp1 == NULL || out_fp2 == NULL){
        fprintf(stderr, "Error : File is not open:errno:%d\n", errno);
        exit(1);
    }
    while(fscanf(in_fp, "%s%d%s",name, &age, gender) != EOF){
        //printf("%s %d %s\n",name, age, gender); //・・・①
        if(age >= ave){
            int result_h = fprintf(out_fp1, "%s  %d\n", name, age);
            //printf("result=%d\n", result_h); //・・・②
        }else{
            int result_l = fprintf(out_fp2, "%s  %d\n", name, age);
            //printf("result=%d\n", result_l); //・・・③
        }
    }
    fclose(in_fp);
    fclose(out_fp1);
    fclose(out_fp2);

    in__fp = fopen("meibo_h.txt", "r");

    printf("*****結果*****\n");
    printf("人数:%d人 平均年齢:%.2f才\n", count, ave);
    printf("-----平均以上-----\n");
    while(fscanf(in__fp, "%s%d", name, &age) != EOF){
        printf("%s\n", name); //・・・④
    }
    printf("**************\n");

    fclose(in__fp);

    return 0;
}

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/07/04 11:05

    ちと補足しておきますと、
    元ソースでは
    > out_fp1 = fopen("meibo_h.txt", "w+");
    で、更新モード(書き込み&読み出し)でオープンしたファイルを書き込みしたあとにそのまま読み出そうとして、そこでエラーとなってプログラムが終了してしまい、あとのfcloseが実行されないため、ファイルの内容が空になったものと思われます

    おそらく、後の読み出しの前に、fseekでファイルポインタを先頭に設定後、読み出すようにすればいけるようになるとは思われますが。

    #いままでw+でファイル操作したことがないので、推測となってしまいます

    ということで、ここらへんの操作を確実にするなら、書き込みが終わった時点でfcloseさせ、改めて読み出しオープンさせるほうがいいでしょうね
    #w+じゃなくてwでオープンするようにしときましょう

    キャンセル

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

  • ただいまの回答率 90.52%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

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

  • C

    3687questions

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