The program given below is equalize all name and surname with last ones. The contents of the students.dat ;
2020102054 Name1 Surname1
2021202051 Name2 Surname2
2020302057 Name3 Surname3
2020802053 Name4 Surname4
2020602059 Name5 Surname5
2019452065 Name6 Surname6
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *stdFptr, *orderFptr;
int student_id ,temp_id[20],ordered_id[20], a=0,i,j;
char student_name[32], student_surname[32];
char *ordered_name[32],*ordered_surname[32],*temp_string[32];
stdFptr = fopen("students.dat","r");
orderFptr = fopen("order.dat","w");
if(!stdFptr || !orderFptr){
puts("File Error, Exiting The Program");
exit(0);
}
else{
puts("Before ordering");
fscanf(stdFptr, "%d %s %s ",&student_id,student_name,student_surname);
while(!feof(stdFptr)){
ordered_name[a] = student_name;
ordered_surname[a] = student_surname;
ordered_id[a] = student_id;
a++;
fprintf(stdout,"%d %s %s\n",student_id,student_name,student_surname);
fscanf(stdFptr, "%d %s %s ",&student_id,student_name,student_surname);
}
ordered_name[a] = student_name;
ordered_surname[a] = student_surname;
ordered_id[a] = student_id;
fprintf(stdout,"%d %s %s\n",student_id,student_name,student_surname);
for(i=0;i<a;i++){
for(j=i+1;j<=a;j++){
if(ordered_id[i]>ordered_id[j]){
temp_string[i] = ordered_name[i];
ordered_name[i] = ordered_name[j];
ordered_name[j] = temp_string[i];
temp_string[i] = ordered_surname[i];
ordered_surname[i] = ordered_surname[j];
ordered_surname[j] = temp_string[i];
temp_id[i] = ordered_id[i];
ordered_id[i] = ordered_id[j];
ordered_id[j] = temp_id[i];
}
}
}
rewind(stdFptr);
fclose(stdFptr);
}
stdFptr = fopen("students.dat","r");
if(!stdFptr || !orderFptr){
puts("File Error, Exiting The Program");
exit(0);
}
else{
puts("After ordering");
i=0;
while(i<=a){
fprintf(orderFptr,"%d\t%s\t\t\t%s\n",ordered_id[i],ordered_name[i],ordered_surname[i]);
fprintf(stdout,"%d %s %s\n",ordered_id[i],ordered_name[i],ordered_surname[i]);
i++;
}
fclose(stdFptr);
fclose(orderFptr);
}
return 0;
}
You have multiple errors in your program.
Errors:
You only have pointers in your array. And you only have one single array for the name. That means you just assign the address of the same array to each of your entries in
ordered_name. Same for the other fields.Just don't do this. See Why is “while ( !feof (file) )” always wrong? why this is wrong.
You use array
temp_idto swap your array entries. First of all, that is very inefficient as you only need a single variable, not an array.Second, this is wrong because you only have 20 elements in
temp_idandordered_idbut 32 elements in the otherordered*arrays.Also you do not care about the number of entries in your file and might overflow both arrays.
Bad practice:
You are using corresponding arrays to store each field of your data sets. That is terrible to maintain. Use a struct instead:
You do not check the result of
fscanfwhich you should always do. Even better, usefgetsfollowed bysscanfto parse your content.You open the file again after you already read all the content. That's not needed.
Your sorting is also inefficient:
This can be used to fully sort an unsorted array. You do this for each new line. Therefore you can rely on the array being sorted. You onle need to find the place where to put the new entry. For this, a single loop would be sufficient.
Or you can move that sorting after you have finished reading the file.
You exit your program in case of an error but you don't report an error to the calling environment
That is same as
exit(EXIT_SUCCESS);. If terminate due to an error, you should also indicate that condition.An improved version could look like this: