bomi
bomi

Reputation: 113

C language text file into struct array

I have a text file which contains student numbers, name, and point line by line. I am trying to add these lines to the struct array..

Example Data in data.txt

723269,Lincoln Burgess,32
543256,Amayah Burnett Bush,63
751201,Robert Downey Jr,73
...
...

My code

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

#define STUDENT_SIZE 273

typedef struct {
  int stNo, points;
  char name[40];
} Student;

int readTxtFile(const char *filename, Student *students) {
  FILE *fin = fopen(filename, "r");
  if (!fin) {
    printf("Can't open file: %s\n", filename);
    return 0;
  }
  int i = 0;
  while (fscanf(fin, "%d,%s,%d",
                &students[i].stNo,
                students[i].name,
                &students[i].points) == 10)
    ++i;

  fclose(fin);
  return i;
}

void printArray(Student *students, int size) {
  for (int i = 0; i < size; i++) {
    Student *st = &students[i];
    printf("%d,%s,%d\n", st->stNo, st->name, st->points);
  }
}

int main() {
  Student students[STUDENT_SIZE];
  char myFile[] = "/Users/can/clang/practice/data.txt";
  int size = readTxtFile(myFile, students);
  printArray(students, size);
  return 0;
}

Code doesn't give error but nothing prints to the console.

Upvotes: 1

Views: 1013

Answers (1)

IrAM
IrAM

Reputation: 1738

If you can use POSIX calls in your system you can use getline function.

getline comes very handy in case if we have to read lines from a file. Then we have to parse the line as per our requirement.

Below i have added the that works for your requirement.

from man page of getline you will have to use these macros at the begining.

Since glibc 2.10:
   _POSIX_C_SOURCE >= 200809L
Before glibc 2.10:
   _GNU_SOURCE

like #define _POSIX_C_SOURCE 200809L


int readTxtFile(const char *filename, Student *students) {
  FILE *fin = fopen(filename, "r");
  if (!fin) {
    printf("Can't open file: %s\n", filename);
    return 0;
  }
  int i = 0;
  
  char *lineptr = NULL;
  size_t size = 0;
  /*
  ssize_t getline(char **lineptr, size_t *n, FILE *stream);
  while (fscanf(fin, "%d%s %d",
                &students[i].stNo,
                students[i].name,
                &students[i].points))
                */
                
                
    while(getline(&lineptr, &size,fin) != -1)
    {
        parse_line_to_struct_members(lineptr, &students[i].stNo, students[i].name,&students[i].points);
        i++;
    }
  free(lineptr);
  lineptr = NULL;
  fclose(fin);
  return i;
}

void parse_line_to_struct_members(char* line, int *num, char* name, int *points)
{
    char* tok = NULL;
    
    // stNo
    tok = strtok(line, ",");
    if(tok)
        *num = atoi(tok);

    //name
    tok = strtok(NULL, ",");
    if(tok)
        strcpy(name, tok);
    
    //points
    tok = strtok(NULL, ",");
    if(tok)
        *points = atoi(tok);
}

Upvotes: 1

Related Questions