2014년 1월 7일 화요일

C언어 : structure를 활용한 파일처리(I/O)

클린코드 읽고 배운대로 함해봄.

목표 :
1) score.txt로부터 성적을 입력받아서, 학생 각각의 평균을 산출하고, 평균을 바탕으로 등수를 매긴다.
2) 이름, 성적, 평균, 등수를 콘솔에 출력한다.
3) 이름, 성적, 등수를 학생이름으로 된 txt파일에 출력한다.

--코드--
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct report{
char* name;
int korean;
int math;
int english;
int number_of_students;
float average;
}REPORT;

int countStudents(FILE* fp_input);
void putInformation(FILE* fp_input, REPORT** reports_pointer, int number_of_students);
void calculateAndPutAverageOfEachStudentInReport(REPORT* reports);
void orderByScore(REPORT* reports);
void printChart(REPORT* reports);
void makeReportFiles(REPORT* reports);

int main()
{
FILE* fp_input;
REPORT* reports;
int number_of_students;
float* average;

fp_input = fopen("score.txt", "r");
if(fp_input == NULL){
fprintf(stderr, "File error!\n");
exit(1);
}

number_of_students = countStudents(fp_input);
rewind(fp_input);
putInformation(fp_input, &reports, number_of_students);
calculateAndPutAverageOfEachStudentInReport(reports);
orderByScore(reports);
printChart(reports);
makeReportFiles(reports);

return 0;
}

int countStudents(FILE* fp_input)
{
int number_of_students=0;
char string_for_count[20];
while(!feof(fp_input)){
fscanf(fp_input, "%s", string_for_count);
number_of_students++;
}
number_of_students /= 4;

return number_of_students;
}

void putInformation(FILE* fp_input, REPORT** reports_pointer, int number_of_students)
{
int i=0;

*reports_pointer = (REPORT*)malloc(sizeof(REPORT)*number_of_students);

while(!feof(fp_input)){
(*reports_pointer)[i].name = (char*)malloc(sizeof(char)*20);
fscanf(fp_input, "%s", (*reports_pointer)[i].name);
fscanf(fp_input, "%d", &(*reports_pointer)[i].korean);
fscanf(fp_input, "%d", &(*reports_pointer)[i].math);
fscanf(fp_input, "%d", &(*reports_pointer)[i].english);
(*reports_pointer)[i].number_of_students = number_of_students;
i++;
}
}

void calculateAndPutAverageOfEachStudentInReport(REPORT* reports)
{
int i=0;
for(i; i<reports[0].number_of_students; i++){
reports[i].average = (float)(reports[i].korean + reports[i].math + reports[i].english) / 3;
}
}

void orderByScore(REPORT* reports)
{
int i, j, temp_korean, temp_math, temp_english;
float temp_average;
char* temp_name;
for(i=0; i<reports[0].number_of_students-1; i++)
for(j=i+1; j<reports[0].number_of_students; j++){
if(reports[i].average < reports[j].average){
temp_average = reports[i].average;
reports[i].average = reports[j].average;
reports[j].average = temp_average;

temp_name = reports[i].name;
reports[i].name = reports[j].name;
reports[j].name = temp_name;

temp_korean = reports[i].korean;
reports[i].korean = reports[j].korean;
reports[j].korean = temp_korean;

temp_math = reports[i].math;
reports[i].math = reports[j].math;
reports[j].math = temp_math;

temp_english = reports[i].english;
reports[i].english = reports[j].english;
reports[j].english = temp_english;
}
}
}

void printChart(REPORT* reports)
{
int i;
printf("      이름        국어  수학  영어   평균     등수\n");
printf("-----------------------------------------------------\n");
for(i=0; i<reports[0].number_of_students; i++)
printf("%15s %5d %5d %5d %8.2f %6d\n", reports[i].name, reports[i].korean, reports[i].math, reports[i].english, reports[i].average, i+1);
}

void makeReportFiles(REPORT* reports)
{
int i;
FILE* fp_output;
for(i=0; i<reports[0].number_of_students; i++){
fp_output = fopen(strcat(reports[i].name, ".txt"), "w");
fprintf(fp_output, "이 름 : %s\n", reports[i].name);
fprintf(fp_output, "국어  : %d\n", reports[i].korean);
fprintf(fp_output, "수학  : %d\n", reports[i].math);
fprintf(fp_output, "영어  : %d\n", reports[i].english);
fprintf(fp_output, "등수  : %d\n", i+1);
}
}

아쉬운점:
* calculateAndPutAverageOfEachStudentInReport는 평균을 계산하는 작업과
평균 값을 각report structure에 넣는 작업 두가지를 한 함수에서 동시에 해결하고 있다.
** 각각의 함수는 출력 인수를 사용하고 있다.

여튼 그래도 ㅈㄴ 뿌듯 ㅎ

댓글 없음:

댓글 쓰기