I have to read data from a .txt file, and then sort them.
I created my method on an other C file, and it worked perfectly, but when I import it, I got this Segmentation fault error.
I try each line of my program, and it seems that my problem is coming from these two functions :
ListScore* fillScore(){
ListScore *list=malloc(sizeof(*list));
FILE* f =NULL;
int score;
char name[20];
f= fopen("score.txt", "r");
if (f==NULL || list==NULL) {
perror("fopen or list Null");
exit(EXIT_FAILURE);
}
while(fscanf(f,"%d%s",&score,name)==2){
insertElem(list,score,name);
}
fclose(f);
bubbleSort(list);
return list;
}
and
void bubbleSort(ListScore* list){
Score_s *get=list->first;
Score_s *move;
/* Checking for empty list */
if (list->first == NULL)
{return;}
else{
while(get->next!=NULL){
move=list->first;
while(move->next!=NULL){
if(move->score<move->next->score){
swap(move,move->next);
}
move=move->next;
printTest();
}
get=get->next;
}
}
}
and debugger show me this condition as the problem
if(move->score<move->next->score);
I can't understand why on an external C file, it worked, but in a complex project (with include.h) it doesn't work.
Thanks in advance.
EDIT : My struct ListScore is defined like this :
typedef struct ListScore{
Score_s *first;
}ListScore;
and Score_s like this
typedef struct Score_s Score_s;
struct Score_s{
char name[20];
int score;
Score_s *next;
};
EDIT 2 : Here's the minimal example, but it works perfectly on it's own... as said in the beginning of this question;
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
typedef struct Score_s Score_s;
struct Score_s{
char name[20];
int score;
Score_s *next;
};
typedef struct ListScore{
Score_s *first;
}ListScore;
void insertElem(ListScore* list,int s,char n[]){
if(list==NULL){
exit(EXIT_FAILURE);
}
Score_s* new;
new=malloc(sizeof(*new));
strcpy(new->name,n);
new->score=s;
new->next=list->first;
list->first=new;
}
void swap(Score_s *a,Score_s *b){
int tmp=a->score;
a->score=b->score;
b->score=tmp;
char tmpS[20];
strcpy(tmpS,a->name);
strcpy(a->name,b->name);
strcpy(b->name,tmpS);
}
void bubbleSort(ListScore* list){
Score_s *get=list->first;
Score_s *move;
/* Checking for empty list */
if (list->first == NULL)
{return;}
else{
while(get->next!=NULL){
move=list->first;
while(move->next!=NULL){
if(move->score<move->next->score){
swap(move,move->next);
}
move=move->next;
}
get=get->next;
}
}
}
void fillScore(){
ListScore *list=malloc(sizeof(*list));
FILE* f =NULL;
int score;
char name[20];
f= fopen("score.txt", "r");
if (f==NULL || list==NULL) {
perror("fopen or list Null");
exit(EXIT_FAILURE);
}
while(fscanf(f,"%s%19d",name,&score)==2){
insertElem(list,score,name);
}
Score_s* new;
new=malloc(sizeof(*new));
new=list->first;
fclose(f);
printf("\n\n");
bubbleSort(list);
new=list->first;
while(new!=NULL){
printf("%s %d\n",new->name,new->score);
new=new->next;
}
free(list);
}
int main(int argc, char const *argv[])
{
fillScore();
return 0;
}
Content of score.txt :
pat 20
ananna 20
radis 19
gg 121
nique 236
perie 125
aziz 127
telma 36
coc 1
aie 6
prout 236
and this is the output :
prout 236
nique 236
aziz 127
perie 125
gg 121
telma 36
ananna 20
pat 20
radis 19
aie 6
coc 1
In the function fillScore
, you are not giving list->first
any value, so that its value is indeterminate. Therefore, after adding elements to the linked list using the function insertElem
, the last element of your linked list does not have a NULL
pointer, but instead has a pointer with an indeterminate value. Eventually, the function bubbleSort
will attempt to deference this indeterminate value, which is probably causing your segmentation fault.
Therefore, you should set list->first
to NULL
.
In your question, you posted two substantially different versions of the function fillScore
. Since I do not know which one you are using, I cannot tell whether there are other issues in the code that you are using.
Also, the line
while(fscanf(f,"%s%19d",name,&score)==2){
does not make sense. You probably intended to write
while(fscanf(f,"%19s%d",name,&score)==2){
instead.
It is also worth noting that your program contains several memory leaks. You are freeing all the memory allocated by the line
ListScore *list=malloc(sizeof(*list));
but all the memory allocated by other calls to malloc
in your program are not being freed. However, this is not the reason for the segmentation fault that you are having.
After fixing all of the issues mentioned above, your code should look like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
typedef struct Score_s Score_s;
struct Score_s{
char name[20];
int score;
Score_s *next;
};
typedef struct ListScore{
Score_s *first;
}ListScore;
void insertElem(ListScore* list,int s,char n[]){
if(list==NULL){
exit(EXIT_FAILURE);
}
Score_s* new;
new=malloc(sizeof(*new));
strcpy(new->name,n);
new->score=s;
new->next=list->first;
list->first=new;
}
void swap(Score_s *a,Score_s *b){
int tmp=a->score;
a->score=b->score;
b->score=tmp;
char tmpS[20];
strcpy(tmpS,a->name);
strcpy(a->name,b->name);
strcpy(b->name,tmpS);
}
void bubbleSort(ListScore* list){
Score_s *get=list->first;
Score_s *move;
/* Checking for empty list */
if (list->first == NULL)
{return;}
else{
while(get->next!=NULL){
move=list->first;
while(move->next!=NULL){
if(move->score<move->next->score){
swap(move,move->next);
}
move=move->next;
}
get=get->next;
}
}
}
void fillScore(){
ListScore *list=malloc(sizeof(*list));
list->first = NULL;
FILE* f =NULL;
int score;
char name[20];
f= fopen("score.txt", "r");
if (f==NULL || list==NULL) {
perror("fopen or list Null");
exit(EXIT_FAILURE);
}
while(fscanf(f,"%19s%d",name,&score)==2){
insertElem(list,score,name);
}
fclose(f);
bubbleSort(list);
Score_s *new = list->first;
while(new!=NULL){
printf("%s %d\n",new->name,new->score);
//remember pointer to previous node so that
//it can be freed after use
Score_s *prev = new;
new=new->next;
//free the pointer to the previous node
free( prev );
}
free(list);
}
int main( void )
{
fillScore();
return 0;
}
With the input specified in the question, this program has the following output:
prout 236
nique 236
aziz 127
perie 125
gg 121
telma 36
ananna 20
pat 20
radis 19
aie 6
coc 1
As you can see, all lines are correctly sorted by score.