Yunus Gedik
Yunus Gedik

Reputation: 190

I'm struggling with the fgets function in C

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define NAMELEN 50
#define MAXRECORD 500

typedef struct record_s {
   int id;
    char number[NAMELEN];
    struct record_s *next;
} Record;

typedef struct person_s {
    int id;
    char name[NAMELEN];
    double expenditure;
    Record *numbers;
} Person;

typedef struct people_s {
    Person data[MAXRECORD];
    int size;
} People;

void read(char* filename, People *people) {
    FILE* fp=fopen(filename,"r");
    int i=0;    //data[i]
    char ilk[NAMELEN]="";   //Name
    char son[NAMELEN]="";   //Surname
    char str[256]="";   //To strtok function.
    char *token;    //To strtok function.

    people->size=0;
    people->data[i].numbers=malloc(sizeof(struct record_s));
    people->data[i].numbers->next=NULL;

    while(fgets(str,256,fp)!=NULL){
        token=strtok(str," ");
        people->data[i].id=atoi(token);
        token=strtok(str," ");
        strcpy(ilk,token);
        token=strtok(str," ");
        strcpy(son,token);
        token=strtok(str," ");
        people->data[i].expenditure=atof(token);
        strcat(ilk," ");
        strcat(ilk,son);
        strcpy(people->data[i].name,ilk);

        token=strtok(str," ");
            people->data[i].numbers->id=people->data[i].id;
        strcpy(people->data[i].numbers->number,token);
        token=strtok(str," ");

        while(token!=NULL){
            people->data[i].numbers->next=malloc(sizeof(struct record_s));
            people->data[i].numbers->next->next=NULL;
            people->data[i].numbers=people->data[i].numbers->next;

            people->data[i].numbers->id=people->data[i].id;
            strcpy(people->data[i].numbers->number,token);
            token=strtok(str," ");

        }

        i++;
        (people->size)++;
    }

    fclose(fp);
}

void print(People people) {
    int i,found = 0;
    Record *rec;
    /* header */
    printf("%-5s %-30s %-20s %-20s\n", "ID","NAME","EXPENDITURE","NUMBER(s)");
    /* line */
    for (i = 0; i < 78; ++i)
    printf("-");
    printf("\n");

    for (i = 0; i < people.size; ++i) {
        found = 0;
        printf("%-5d %-30s %-20.4f", people.data[i].id, people.data[i].name,         people.data[i].expenditure);
        rec = people.data[i].numbers;
        while(rec) {
            if(found)
                printf("%57s", "");
            else
                found = 1;
            printf("%-20s\n", rec->number);
            rec = rec->next;
        }
        printf("\n");
    }
}


int main(int argc, char** argv) {
    People people1,people2;
    people1.size = 0;
    read(argv[1],&people1);
    print(people1);
    return 0;
}

I get core dum so try to look at gdb and this comes up:

Program received signal SIGSEGV, Segmentation fault. _IO fgets (buf=0x7fffffff 5150 "", n=256, fp=0x0) at iofgets.c:50 50 iofgets.c: No such file or directory.

And I have no idea why I'm gettin seg fault.

My text file:

123 Asaf Avidan 25.2 05411975476 02224759866
221 Goksel Baktagir 12.4 03127586632
122 Goran Bregovic 10 02167418632
101 Marjan Farsad 27.8 05558741937 0555279431
36 Mark Eliyahu 36.6 05412147596 05423214587 05335841937
27 Mohsen Namjoo -1 05421458698 05447851489
192 Erkan Ogur 49.5 02162547896 02125847596 05325874586 05335412586

I'm trying to read ıd,name,a float and phone numbers which ı dont know which person have how many so I use fgets() function to read text file line by line and breaks the string that I gets from fgets into tokens by strtok() fucntion.

Upvotes: 1

Views: 596

Answers (1)

alk
alk

Reputation: 70981

fopen() can fail. It then returns NULL, Trying to read from NULL makes fgets() choke.

This

fgets (buf=0x7fffffff 5150 "", n=256, fp=0x0)

tells you that 0 had been passed as value for the file-pointer to "read" from. NULL most often is implemented as 0.

You want to add error checking for all functions that might fail.

You can do so for example like this:

   FILE* fp=fopen(filename,"r");
   if (NULL == fp)
   {
     perror("fopen() failed");
     exit(EXIT_FAILURE); /* include <stdlib.h> to have the EXIT_* macros available. */
   }

Upvotes: 1

Related Questions