The Student struct I offered contains an anonymous union.
The n member (number of classes) and the GPA member
(GPA average of student) can both be addressed in the same
way as any of the other struct members (. or -> notation)
As you can see I use n for input from user and GPA for
input from file (GPA average).
Try it out, it works. In case that is awkward you could
introduce 2 structs one with an int and the other with
a float member.
The last paragraph of your assignment is partly implemented ...
scanf's problem is that there are always some user inputs pending
in the keyboard buffer. I handled this with fgets and sscanf. However
you also could read this:
http://stackoverflow.com/questions/17248442/flushing-stdin-after-every-input-which-approach-is-not-buggy
and adapt your code accordingly.
Here is the code:
#include
#include
struct Student {
char szName[64];
int id;
union {
int n;
float GPA;
};
};
float Fun_GPA(int);
void get_student(struct Student *);
void find_GPA_HIGH(struct Student *, const int, const char *);
int main()
{
const char szFile[] = "STUDENTS";
float GPA = 0.0f;
struct Student s;
struct Student highest;
int m = 0;
char line[64];
printf("Number of student> ");
fgets(line, sizeof(line), stdin);
sscanf(line, "%d", &m);
FILE *f = fopen(szFile, "wt");
for (int i = 0; i < m; i++) {
get_student(&s);
float n = Fun_GPA(s.n);
s.szName[strlen(s.szName) - 1] = 0;
fprintf(f, "%s\n%d\n%g\n", s.szName, s.id, n);
}
fclose(f);
m = 3;
find_GPA_HIGH(&highest, m, szFile);
fprintf(stdout, "\nStudent with highest GPA\n%s\n%d\n%.2f\n", highest.szName, highest.id, highest.GPA);
return EXIT_SUCCESS;
}
void get_student(struct Student *s)
{
char line[128];
printf("name> ");
fgets(s->szName, sizeof(s->szName), stdin);
printf("id ");
fgets(line, sizeof(line), stdin);
sscanf(line, "%d", &s->id);
printf("How many courses> ");
fgets(line, sizeof(line), stdin);
sscanf(line, "%d", &s->n);
}
float Fun_GPA(int iCourseNumber)
{
float fSum = 0;
int iGrade = 0;
char buffer[124];
for (int i = 0; i < iCourseNumber; i++) {
printf("Grade for Course %d> ", i + 1);
fgets(buffer, sizeof(buffer), stdin);
sscanf(buffer, "%d", &iGrade);
fSum += iGrade;
}
fSum /= iCourseNumber;
return fSum;
}
void find_GPA_HIGH(struct Student *highest, const int m, const char *szFilename)
{
FILE *f;
struct Student s;
s.GPA = 0.0f;
f = fopen(szFilename, "rt");
if (!f) {
fprintf(stdout, "Could not open file %s\n", szFilename);
return;
}
char line[64];
for (int i = 0; i < m; i++) {
fgets(s.szName, sizeof(s.szName), f);
fgets(line, sizeof(line), f);
sscanf(line, "%d", &s.id);
fgets(line, sizeof(line), f);
sscanf(line, "%f", &s.GPA);
if (s.GPA > highest->GPA) {
*highest = s;
}
}
fclose(f);
}