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

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

ただいまの
回答率

91.03%

  • 配列

    451questions

    配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

  • ファイル

    143questions

    ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

あと少しなんですがうまくいきません、、、

解決済

回答 1

投稿 編集

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

szkdma

score 3

C
C言語で
各学生の学籍番号・物理の点数・化学の点数の組がスペース区切りで一行に記述されたファイルを読み込み,全学生の物理の平均点・最高点・最低点,および化学の平均点・最高点・最低点を別のファイルに書き出すプログラムで、入力するファイル名および出力するファイル名を指定できるようにすること。
また、学籍番号・物理の点数・化学の点数の 3 つのメンバを持つ構造体 struct student_data を宣言し,さらに typedef 宣言を用いて struct student_data 型を student として参照できるようにせよ. 
そして、student型の配列 s[10] を宣言し入力データファイルを読み込んで,この配列にデータをセットし、キーボードから,科目番号(物理なら1, 化学なら2),点数の上限,および下限を入力し,その範囲内の点数を持つ学生の学籍番号とその点数を出力ファイルに書き出すプログラムを作成せよ
というプログラムを作成したいのですがうまくいきません。
<データ>
9001 92 77
9002 51 66
9003 56 96
9004 64 89
9005 88 74
9006 89 78
9007 74 76
9008 69 80
9009 67 96
9010 59 67

例えば、化学の70-80点とした場合、9001番の学生がなぜか出ません
いまいちよくわかっていないので間違いを指摘していただきたいです。

該当のソースコード

include<stdio.h>

include<stdlib.h>

include<string.h>

define STRING_SIZE  200

typedef struct student_data{
int num;
int phys;
int chem;
}student;

int main(void)
{
int num,phys,chem;
char FileNamein[14];
char FileNameout[14];
student s[10];

char buf[STRING_SIZE];
FILE *fpin,*fpresult;

printf("入力>>>");
scanf("%s",&FileNamein);

printf("出力>>>");
scanf("%s",&FileNameout);

if((fpin=fopen(FileNamein,"r"))==NULL)
{
printf("ファイルが見つかりません---%s\n",FileNamein);
exit(EXIT_FAILURE);
}

if((fpresult=fopen(FileNameout,"w"))==NULL)
{
fclose(fpin);
printf("ファイルが作成できません---%s\n",FileNameout);
exit(EXIT_FAILURE);
}

int kamoku;
printf("科目>>>");
scanf("%d",&kamoku);

int jou,kag;
printf("\n上限");
scanf("%d",&jou);
printf("\n下限");
scanf("%d",&kag);

int i;
while(fgets(buf,STRING_SIZE,fpin))
{
for(i=0;i<10;i++)
{
fscanf(fpin,"%d %d %d",&s[i].num,&s[i].phys,&s[i].chem);    
if(kamoku==1)
{
if(s[i].phys>=kag&&s[i].phys<=jou)
{
fprintf(fpresult,"%d %d \n",s[i].num,s[i].phys);
}
}
if(kamoku==2)
{
if(s[i].chem>=kag&&s[i].chem<=jou)
{
fprintf(fpresult,"%d %d \n",s[i].num,s[i].chem);
}
}

}
}

fclose(fpin);
fclose(fpresult);

return EXIT_SUCCESS;

}

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • LouiS0616

    2017/12/29 03:02

    タグがCじゃなくてC#になっちゃってますよ。また、コードはコードブロックで囲んでください。コードを選択した状態で<code>ボタンを押すと適用されます。

    キャンセル

回答 1

checkベストアンサー

+4

ファイルを読み込む際、二重ループが完全に無駄です。
一行目だけをfgetsで読み込んでしまっているので、9001のデータが出力されていません。

while(fgets(buf, STRING_SIZE, fpin)) {
    for(i = 0; i < 10; i++) {
        fscanf(fpin, "%d %d %d", &s[i].num, &s[i].phys, &s[i].chem);
        ...
    }
}

外側のループを削除してください。

質問の仕方について

teratailでは、上記のようにコードを見やすく表示する機能があります。
質問編集画面を開き、コードを選択した状態で<code>ボタンを押してください。
インデントが残る他、#も正しく表示されます。

また、質問のタグにはご注意ください。CとC#は別の言語です。

おまけ

個人的には、こんな感じで書きますね。

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

#define NUM_OF_STUDENTS 10

typedef struct {
    int num, phys, chem;
} Student;

typedef enum {
    PHYSICS = 1, CHEMICAL, ALL = -1,
} Subjects;

int fscan_student(FILE *fp, Student *dst) {
    return fscanf(
        fp, "%d %d %d", &dst->num, &dst->phys, &dst->chem
    );
}
int fprint_student(FILE *fp, const Student *src, const Subjects subject) {
    switch(subject) {
    case PHYSICS:
        return fprintf(
            fp, "%d %d\n", src->num, src->phys
        );       
    case CHEMICAL:
        return fprintf(
            fp, "%d %d\n", src->num, src->chem
        );   
    default:
        return fprintf(
            fp, "%d %d %d\n", src->num, src->phys, src->chem
        ); 
    }
}
bool in_range_student(
    const Student *src, Subjects subject, int lower, int upper) {

    switch(subject) {
    case PHYSICS:
        return lower <= src->phys && src->phys <= upper;
    case CHEMICAL:
        return lower <= src->chem && src->chem <= upper;
    default:
        return false;
    }
}

//
//
//
int main(int argc, char **argv) {
    //
    // Prepare Files
    if(argc < 3) {
        printf("USAGE: exam.exe src_file_name dst_file_name\n");
        return EXIT_FAILURE;
    }
    char *file_in  = argv[1];
    char *file_out = argv[2];

    FILE *fp_in = fopen(file_in, "r");
    if(fp_in == NULL) {
        printf("ファイルが見つかりません---%s\n", file_in);
        return EXIT_FAILURE;
    }

    FILE *fp_out = fopen(file_out, "w");
    if(fp_out == NULL) {
        fclose(fp_in);
        printf("ファイルが作成できません---%s\n", file_out);
        exit(EXIT_FAILURE);
    }

    //
    // Read Data
    Student students[NUM_OF_STUDENTS];
    for(int i = 0; i < NUM_OF_STUDENTS; ++i) {
        fscan_student(fp_in, &students[i]);
        fprint_student(stdout, &students[i], ALL);    // for debug
    }

    //
    // Select Students
    int subject;
    printf("subject(phys: 1, chem: 2) >>> ");
    if(scanf("%d", &subject) != 1) return EXIT_FAILURE;

    int upper, lower;
    printf("upper limit: "); 
    if(scanf("%d", &upper) != 1) return EXIT_FAILURE;

    printf("lower limit: ");
    if(scanf("%d", &lower) != 1) return EXIT_FAILURE;

    for(int i = 0; i < NUM_OF_STUDENTS; ++i) {
        if(in_range_student(&students[i], subject, lower, upper)) {
            fprint_student(fp_out, &students[i], subject);
        }
    }

    //
    // Termination
    fclose(fp_in);
    fclose(fp_out);
    return EXIT_SUCCESS;
}

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/12/29 13:15

    いろいろとご指摘ありがとうございます!
    もう一度ループのところから考え直してみます!

    キャンセル

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

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

関連した質問

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

  • 配列

    451questions

    配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

  • ファイル

    143questions

    ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。