I need to filter students by the courses they take. I need to filter students, who has "Algebra", but I can't figure it out, because in the first if statement it prints all of the students. But I need to filter with the second if statement by the courses. What should I do with the first if statement?
#include <stdio.h>
#include <stdlib.h>
typedef struct Student {
char name[30];
char surname[30];
int course; // year of study
double average; // average grade
int load; // number of courses
char courses[10][30]; // course names
int grades[10]; // course grades
char languages[100]; // spoken languages
} Student;
int main(int argc, char *argv[]) {
FILE *db = NULL;
// open database file for reading, provide a parameter or use default "db.bin"
if (argc > 1)
db = fopen(argv[1], "rb");
else
db = fopen("db.bin", "rb");
if (db){
Student students[1000]; // all the data goes here
int size = 0; // how many students in database
// reading data from file
fread(&size, sizeof(int), 1, db);
for (int i = 0; i < size; i++){
fread(&students[i], sizeof(Student), 1, db);
}
printf("%d records loaded succesfully\n", size);
// MODIFY CODE BELOW
int counterDemo = 0; // for counting students
for (int i = 0; i < size; ++i){ // process all the student records in database
Student s = students[i]; // store data for each student in s
if(1){ // *** first filter, conditions on the student
printf("%s%s%d%f%d", s.name, s.surname, s.course, s.average, s.load); // print student data
int anotherDemo = 0; // for counting courses/grades
for (int i = 0; i < s.load; ++i){ // process each course taken by the student
if(s.courses[][]){ // *** second filter, conditions on the course/grade
++anotherDemo; // counting courses
printf("%s%d", s.courses[i], s.grades[i]);
}
}
printf("%s\n", s.languages);
if (anotherDemo == s.load) // *** third filter, various other conditions
++counterDemo; // counting studfents
}
}
printf("Filter applied, %d students found\n", counterDemo); // how many passed the filters
fclose(db);
} else {
printf("File db.bin not found, check current folder\n");
}
return 0;
}
This is a partial re-write (not compiled and not tested) of your code, based on what it appears you want to achieve. This may suggest an approach that you might follow to get where you want to be. (There may be typos in here, but the general scheme should help you move forward.)
int filterLoad( Student *p, int n ) {
return p->load >= n;
}
int filterCourse( Student *p, char *pCourse, int minGrade ) {
for( int i = 0; i < sizeof p->courses/sizeof p->courses[0]; i++ )
if( strcmp( p->courses[ i ], pCourse ) == 0
&& p->grades[ i ] >= minGrade )
return 1; // qualifies
return 0; // does not qualify
}
void showStudent( int cnt, Student *p ) {
printf( "%d: %s, %s\n", cnt, p->surname, p->name );
/* more printing, including finding Algebra mark again, etc. */
}
int main( int argc, char *argv[] ) {
char dbName = "db.bin"; //default
if( argc > 1 )
dbName = argv[1];
FILE *db = fopen( dbName, "rb" );
if( db == NULL ) {
fprintf( stderr, "Cannot open '%s'. Check current folder\n", dbName );
return 1;
}
Student students[1000];
int size = 0;
fread( &size, sizeof size, 1, db ); // # of records to load
for( int i = 0; i < size; i++ )
fread( &students[i], sizeof students[0], 1, db );
fclose( db ); // done with file
printf( "%d records loaded succesfully\n", i );
int counter = 0;
for( int i = 0; i < size; i++ ) {
Student *pStu = students[ i ];
if( filterCourse( pStu, "Algebra", 70 ) // attained min 70 in Algebra
&& filterLoad( pStu, 3 ) ) // and min of 3 subjects
showStudent( ++counter, pStu );
}
printf( "%d matching students found\n", counter );
return 0;
}
There's no reason to read up to 1000 records at once. You could use just a single buffer to load one-record-at-at-time. It's your choice.
int main( int argc, char *argv[] ) {
char dbName = "db.bin"; //default
if( argc > 1 )
dbName = argv[1];
FILE *db = fopen( dbName, "rb" );
if( db == NULL ) {
fprintf( stderr, "Cannot open '%s'. Check current folder\n", dbName );
return 1;
}
fseek( db, sizeof(int), SEEK_SET ); // step over useless number
int counter = 0;
Student one;
for( int i = 0; fread( &one, sizeof one, 1, db ) != NULL; i++ )
if( filterCourse( &one, "Algebra", 70 )
&& filterLoad( &one, 3 ) )
showStudent( ++counter, &one );
fclose( db );
printf( "%d student records examined\n", i );
printf( "%d matching students found\n", counter );
return 0;
}