-1
#define MAXROW 30

typedef struct emp_info {
    int emp_id;
    char *name;
    char *dept;
    int salary;
} emp_info;

void store(emp_info *data,  char *filename);

int main(int argc, char **argv)
{
    int preceding;
    int following;
    emp_info data[MAXROW] ;
    // emp_info data[MAXROW] = {{.salary = 0 }};
    char *filename = "dat/emp_info.csv";
    store(data,filename);
    return 0;
}


void store(emp_info emp_arr[],  char *filename)
{
    size_t n = 0;
    char  *line;
    FILE *csv_stream;
    if((csv_stream = fopen(filename,"r")) == NULL){
        fprintf(stderr,"file open for reading failed. exit!\n");
        exit(EXIT_FAILURE);
    }

    while ( n < MAXROW && (fgets(line,sizeof line, csv_stream)) != NULL)
    {   
        emp_info tmp;
        if(sscanf(line,"%d,%29[^,],%29[^,],%d",
            &tmp.emp_id,tmp.name,tmp.dept,&tmp.salary) != 4)
        {
            fprintf(stderr,"error: failed to parse string.\n");
            exit(EXIT_FAILURE);
        }
        emp_arr[n++] = tmp;
    }

    if(fclose(csv_stream) == EOF)
        perror("stream error-csv_stream.");
}

ERROR: Segmentation fault (core dumped) Idea is trying to get values from csv file(less than 10 rows) to array of struct emp_info.
code link: https://godbolt.org/z/h5h1K11T6

update


emp_info.csv :

1,alice,depa,1000
2,bob,depa,2000
3,carol,depb,1501
4,david,depa,1200
5,ed,depc,1306

After fix segment fault, now the issue is parse csv content. Now the error is fail to parse string.
I feel like my sscanf pattern should work. But it doesn't.

I also tried:

  if(sscanf(line,"%d,%19[^,],%19[^,],%d\n",
        &tmp.emp_id,tmp.name,tmp.dept,&tmp.salary) != 4)

But still cannot parse csv content.

jian
  • 4,119
  • 1
  • 17
  • 32
  • 1
    Now seems like a *very* good time to learn how to [*debug*](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/) your programs. More specifically how to use a [*debugger*](https://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems) to catch crashes as and when they happen, and locate where in your code it happens, and examine all involved variables at the time of the crash to see their values. – Some programmer dude Aug 25 '22 at 11:03
  • 6
    A big hint though: `fgets(line,sizeof line, csv_stream)`? Where is `line` pointing? What is its size? – Some programmer dude Aug 25 '22 at 11:04
  • 1
    Just a tip... When you get it working, the function name might be better if it were `load()` rather than `store()`... More conventional to think of "loading data from file" and "storing data to file"... – Fe2O3 Aug 25 '22 at 11:14
  • @Fe2O3 thanks. Now the problem is the sscanf issue, can you spare sometime check it. – jian Aug 25 '22 at 11:28
  • Sorry, no. @Someprogrammerdude told you were to begin to solve this problem. "Where is line pointing?" You cannot `sscanf( )` from somewhere unknown. In fact, you cannot `fgets( )` to that unknown space either (without creating havoc.) Explain the code to your rubber duck, slowly and methodically... Pay attention to hints given by people... – Fe2O3 Aug 25 '22 at 11:35
  • And, when you have resolved the issue of the `line` pointer, you'll have the exact same one repeated (twice) with the `tmp.name` and `tmp.dept` pointers. – Adrian Mole Aug 25 '22 at 12:41

1 Answers1

0

refactored code:

#define MAXROW 30
#define MAXC 50

typedef struct emp_info {
    int emp_id;
    char name[MAXC];
    char dept[MAXC];
    int salary;
} emp_info;

size_t load(emp_info emp_arr[],  char *filename);

int main(int argc, char **argv)
{
    int preceding;
    int following;
    emp_info data[MAXROW] = {{.emp_id = 0}};

    char *filename = "dat/emp_info.csv";
    size_t real_size = load(data,filename);

    for(int j = 0; j < real_size; j++){
        if (data[j].emp_id == 0) 
            break;

        printf("%d\t%s\t%s\t%d\n",data[j].emp_id,data[j].name,data[j].dept,data[j].salary);
    }
    printf("size of data: %lu\n", sizeof data / sizeof *data);

    return 0;
}


size_t load(emp_info emp_arr[],  char *filename)
{
    size_t n = 0;
    char  line[MAXC] = {0};

    FILE *csv_stream;
    if((csv_stream = fopen(filename,"r")) == NULL){
        fprintf(stderr,"file open for reading failed. exit!\n");
        exit(EXIT_FAILURE);
    }

    while ( n < MAXROW && (fgets(line,sizeof line, csv_stream)) != NULL)
    {   
        emp_info tmp;
        if(sscanf(line,"%d,%[^,],%[^,],%d",
            &tmp.emp_id,tmp.name,tmp.dept,&tmp.salary) != 4)
        {
            fprintf(stderr,"error: failed to parse string.\n");
            exit(EXIT_FAILURE);
        }
        emp_arr[n++] = tmp;
    }
    

    if(fclose(csv_stream) == EOF)
        perror("stream error-csv_stream.");
    
    return n;

}
jian
  • 4,119
  • 1
  • 17
  • 32