We have a school assignment, in which the program is to read data of students from stdin, in the following format: LASTNAME FIRSTNAME STUDENT_ID SUBJECT AVERAGE_GRADES. The program has to print out the data of students with the top 3 averages, whose subject is the same as the one given in the first line in a similar format as the input, only leaving out the subject. If two students have the same averages, their data should be in a decreasing lexographical order of their STUDENT_ID.
So I can write the program and it works properly, but the last time during practice my teacher looked at my screen and bragged, that he could do the same problem in about 30-50 lines of code. My question is, can you give me some hints, whether there is any superfluous lines in my code? Is there anything that I overcomplicate, or just could be done in a simpler, more professional way?
Example Input:
CS
Jane Doe 123ABC GI 4.5
Mark Spencer AFG12L GI 4.4
Charlotte Fringe LUK65E CS 4.0
Stephen Wright ART12M CS 2.8
Christine Smith ERTZ12 IE 2.7
Adam Lee ZTI98M GI 3.4
Juliette Johnson ARE74W CS 4.0
Kevin Crane QWER99 IE 2.6
Jessica Rhoades ASDF89 GI 2.5
Mark Mason ACDC12 IE 3.8
Jules Shepard XYC78L CS 4.9
Example Output:
Jules Shepard XYC78L 4.9
Juliette Johnson ARE74W 4.0
Charlotte Fringe LUK65E 4.0
And the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct student_data {
char firstname[30];
char lastname[30];
char neptun_code[7];
char subject[10];
float average;
};
int main()
{
int i; // outer incrementation counter
int j; // inner incrementation counter
int line_num = 0;
int printed_lines = 0;
int attr_counter;
char subject_given[10];
char *string_buffer = malloc(1000 * sizeof(char));
char *token_buffer = malloc(1000 * sizeof(char));
struct student_data student_data_all[1000];
struct student_data top_three[3];
struct student_data swap_buffer; // needed for sorting
//read in lines from stdin in the format of LASTNAME FIRSTNAME STUDENT_ID SUBJECT AVERAGE_GRADES
while(fgets(string_buffer, 1000, stdin) != NULL && string_buffer[0] != '\n')
{
//read in the first line which contains a subject name, then trim the trailing \n, this will be needed for strcmp to work properly at the end of the code
if(line_num == 0)
{
token_buffer = strtok(string_buffer, "\n");
strcpy(subject_given, token_buffer);
line_num++;
continue;
}
//fill up the structure array with relevant data using whitespace as a delimiter
attr_counter = 0;
token_buffer = strtok(string_buffer, " ");
while(token_buffer != NULL)
{
if(attr_counter == 0)
strcpy(student_data_all[line_num - 1].lastname, token_buffer);
else if(attr_counter == 1)
strcpy(student_data_all[line_num - 1].firstname, token_buffer);
else if(attr_counter == 2)
strcpy(student_data_all[line_num - 1].neptun_code, token_buffer);
else if(attr_counter == 3)
strcpy(student_data_all[line_num - 1].subject, token_buffer);
else if(attr_counter == 4)
student_data_all[line_num - 1].average = strtod(token_buffer, NULL);
token_buffer = strtok(NULL, " ");
attr_counter++;
}
line_num++;
}
//sort the student_data_all structure in decreasing order of average
for(i = 0; i < line_num -1; i++)
{
for(j = i + 1; j < line_num -1; j++)
{
if(student_data_all[i].average < student_data_all[j].average)
{
swap_buffer.average = student_data_all[i].average;
strcpy(swap_buffer.firstname, student_data_all[i].firstname);
strcpy(swap_buffer.lastname, student_data_all[i].lastname);
strcpy(swap_buffer.neptun_code, student_data_all[i].neptun_code);
strcpy(swap_buffer.subject, student_data_all[i].subject);
student_data_all[i].average = student_data_all[j].average;
strcpy(student_data_all[i].firstname, student_data_all[j].firstname);
strcpy(student_data_all[i].lastname, student_data_all[j].lastname);
strcpy(student_data_all[i].neptun_code, student_data_all[j].neptun_code);
strcpy(student_data_all[i].subject, student_data_all[j].subject);
student_data_all[j].average = swap_buffer.average;
strcpy(student_data_all[j].firstname, swap_buffer.firstname);
strcpy(student_data_all[j].lastname, swap_buffer.lastname);
strcpy(student_data_all[j].neptun_code, swap_buffer.neptun_code);
strcpy(student_data_all[j].subject, swap_buffer.subject);
}
}
}
//in case two students have the same average, they should be listed in the increasing order of their student id, this conditional sorting is done here
for(i = 0; i < line_num -1; i++)
{
for(j = i + 1; j < line_num -1; j++)
{
if(student_data_all[i].average == student_data_all[j].average)
{
if(strcmp(student_data_all[i].neptun_code,student_data_all[j].neptun_code) > 0)
{
swap_buffer.average = student_data_all[i].average;
strcpy(swap_buffer.firstname, student_data_all[i].firstname);
strcpy(swap_buffer.lastname, student_data_all[i].lastname);
strcpy(swap_buffer.neptun_code, student_data_all[i].neptun_code);
strcpy(swap_buffer.subject, student_data_all[i].subject);
student_data_all[i].average = student_data_all[j].average;
strcpy(student_data_all[i].firstname, student_data_all[j].firstname);
strcpy(student_data_all[i].lastname, student_data_all[j].lastname);
strcpy(student_data_all[i].neptun_code, student_data_all[j].neptun_code);
strcpy(student_data_all[i].subject, student_data_all[j].subject);
student_data_all[j].average = swap_buffer.average;
strcpy(student_data_all[j].firstname, swap_buffer.firstname);
strcpy(student_data_all[j].lastname, swap_buffer.lastname);
strcpy(student_data_all[j].neptun_code, swap_buffer.neptun_code);
strcpy(student_data_all[j].subject, swap_buffer.subject);
}
}
}
}
//print out three students with the top averages
for(i = 0; i < line_num - 1; i++)
{
if(strcmp(student_data_all[i].subject, subject_given) == 0)
{
printf("%s %s %s %.1f\n", student_data_all[i].lastname,student_data_all[i].firstname, student_data_all[i].neptun_code, student_data_all[i].average);
printed_lines++;
if(printed_lines == 3)
break;
}
}
return 0;
}
fscanf()
is your friend for reading data. \$\endgroup\$ – Martin York Jun 14 '17 at 23:00