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

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

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

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

配列

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

Q&A

解決済

1回答

417閲覧

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

_sfgh3k

総合スコア18

ファイル

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

配列

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

0グッド

0クリップ

投稿2017/12/28 17:56

編集2017/12/29 04:13

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;

}

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

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

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

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

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

LouiS0616

2017/12/28 18:02

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

回答1

0

ベストアンサー

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

C

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

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

質問の仕方について

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

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

おまけ

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

C

1#include <stdbool.h> 2#include <stdio.h> 3#include <stdlib.h> 4 5#define NUM_OF_STUDENTS 10 6 7typedef struct { 8 int num, phys, chem; 9} Student; 10 11typedef enum { 12 PHYSICS = 1, CHEMICAL, ALL = -1, 13} Subjects; 14 15int fscan_student(FILE *fp, Student *dst) { 16 return fscanf( 17 fp, "%d %d %d", &dst->num, &dst->phys, &dst->chem 18 ); 19} 20int fprint_student(FILE *fp, const Student *src, const Subjects subject) { 21 switch(subject) { 22 case PHYSICS: 23 return fprintf( 24 fp, "%d %d\n", src->num, src->phys 25 ); 26 case CHEMICAL: 27 return fprintf( 28 fp, "%d %d\n", src->num, src->chem 29 ); 30 default: 31 return fprintf( 32 fp, "%d %d %d\n", src->num, src->phys, src->chem 33 ); 34 } 35} 36bool in_range_student( 37 const Student *src, Subjects subject, int lower, int upper) { 38 39 switch(subject) { 40 case PHYSICS: 41 return lower <= src->phys && src->phys <= upper; 42 case CHEMICAL: 43 return lower <= src->chem && src->chem <= upper; 44 default: 45 return false; 46 } 47} 48 49// 50// 51// 52int main(int argc, char **argv) { 53 // 54 // Prepare Files 55 if(argc < 3) { 56 printf("USAGE: exam.exe src_file_name dst_file_name\n"); 57 return EXIT_FAILURE; 58 } 59 char *file_in = argv[1]; 60 char *file_out = argv[2]; 61 62 FILE *fp_in = fopen(file_in, "r"); 63 if(fp_in == NULL) { 64 printf("ファイルが見つかりません---%s\n", file_in); 65 return EXIT_FAILURE; 66 } 67 68 FILE *fp_out = fopen(file_out, "w"); 69 if(fp_out == NULL) { 70 fclose(fp_in); 71 printf("ファイルが作成できません---%s\n", file_out); 72 exit(EXIT_FAILURE); 73 } 74 75 // 76 // Read Data 77 Student students[NUM_OF_STUDENTS]; 78 for(int i = 0; i < NUM_OF_STUDENTS; ++i) { 79 fscan_student(fp_in, &students[i]); 80 fprint_student(stdout, &students[i], ALL); // for debug 81 } 82 83 // 84 // Select Students 85 int subject; 86 printf("subject(phys: 1, chem: 2) >>> "); 87 if(scanf("%d", &subject) != 1) return EXIT_FAILURE; 88 89 int upper, lower; 90 printf("upper limit: "); 91 if(scanf("%d", &upper) != 1) return EXIT_FAILURE; 92 93 printf("lower limit: "); 94 if(scanf("%d", &lower) != 1) return EXIT_FAILURE; 95 96 for(int i = 0; i < NUM_OF_STUDENTS; ++i) { 97 if(in_range_student(&students[i], subject, lower, upper)) { 98 fprint_student(fp_out, &students[i], subject); 99 } 100 } 101 102 // 103 // Termination 104 fclose(fp_in); 105 fclose(fp_out); 106 return EXIT_SUCCESS; 107}

投稿2017/12/28 18:51

編集2017/12/28 19:23
LouiS0616

総合スコア35660

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

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

_sfgh3k

2017/12/29 04:15

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問