Reputation: 11
I am trying to write a C code that reads a txt file and collects the student name and grades from the text file, displays them in a list, then gives each student's average grade.
The content of the txt file is this:
Cersie 22 16
Arya 90 96
Ramsay 3 5
Daenerys 90 35
Jon 93 93
Theon 60 85
The code I have so far is this:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int rec; //reclare rec as number of records read from file as global variable so as to
access it any where
//method to read the data from file and store them into corresponding arrays
int getRecord(char name[100][20],double firstEx[100],double secondEx[100])
{
int i=0;
FILE *inputFile = fopen("data.txt","r");//open the file in read mode
//condition for unable to open the file
if(inputFile==NULL)
{
printf("\n Unable to open the file.");
exit(0);
}
//loop to read the file and store them into arrays
while(fscanf(inputFile,"%s%lf%lf",name[i],&firstEx[i],&secondEx[i])!=EOF)
{
i++;//increase the number of files
}
return i;//return number of records read from file
}
//method to arrange the records in descending order
void calculateAverageGrade(char name[100][20],double firstEx[100],double
secondEx[100],double average[100])
{
int i;
//loop to compute the average of all the students
for(i=0;i<rec;i++)
{
average[i]=(firstEx[i]+secondEx[i])/2;
}
}
void sortRecord(char name[100][20],double firstEx[100],double secondEx[100],double
average[100])
{
//loop to arrange the records in descending order of average
int i,j;
double t;
char temp[20];
for(i=0;i<rec;i++)
{
for(j=i+1;j<rec;j++)
{
if(average[i]<average[j])
{
//swap firstExam score
t=firstEx[i];
firstEx[i]=firstEx[j];
firstEx[j]=t;
//swap secondExam Score
t=secondEx[i];
secondEx[i]=secondEx[j];
secondEx[j]=t;
//swap average
t=average[i];
average[i]=average[j];
average[j]=t;
//swap names
strcpy(temp,name[i]);
strcpy(name[i],name[j]);
strcpy(name[j],temp);
}
}
}
}
//method to print the records in descending order
void printRecord(char name[100][20],double firstEx[100],double secondEx[100],double
average[100])
{
int i;
printf("\nStudent Exam Record\nName\tExam One\tExam Two\tAverage");
for(i=0;i<rec;i++)
printf("\n%s\t%8.lf\t%8.lf\t%7.2lf",name[i],firstEx[i],secondEx[i],average[i]);
}
//method to display the top scorer
void displayTopScorer(char name[100][20],double average[100])
{
float max=average[0];
printf("\n\nTop Scorer");
for(int i=0;i<rec;i++){
if(average[i]==max)
printf("\n%s",name[i],average[i]);
}
}
//driver code
int main()
{
char name[100][20];
double firstEx[100],secondEx[100],average[100];
int i;
//call to getRecord()
rec=getRecord(name,firstEx,secondEx);
//call to calculateAverageGrade()
calculateAverageGrade(name,firstEx,secondEx,average);
//call to sortRecord()
sortRecord(name,firstEx,secondEx,average);
printRecord(name,firstEx,secondEx,average);
//call to displayTopScorer()
displayTopScorer(name,average);
}
The issue I'm having is that in my output, the spacing for Daenerys's grades is different than the grades for the rest of the students, as shown below:
Student Exam Record
Name Exam One Exam Two Average
Arya 90 96 93.00
Jon 93 93 93.00
Theon 60 85 72.50
Daenerys 90 35 62.50
Cersie 22 16 19.00
Ramsay 3 5 4.00
Would anyone be able to correct my code to fix this?
Upvotes: 1
Views: 814
Reputation: 117268
The problem is in your printf
s. When you use %s\t
it will print the string followed by a tabulator character - but that will make it end up at different tabulator positions depending on the length of the string. Make it %-21s
(or similar) instead. The -
is to make it left justified. 21
is the width you want for that field. Make the width as large as the longest string you allow for the field.
Upvotes: 2