Home > Software engineering >  read data from txt file into a struct in C
read data from txt file into a struct in C

Time:12-20

Hi I am trying to read a comma seprated file into a struct in c. the problem is they have spaces in between the same sentence so fscanf doesnt work well.

Text file:

9780136019701,An Introduction to Organic Chemistry,Timberlake Karen,10,3.54,12-2008
9781506304212,Mathematics for Social Scientists,Kropko Jonathan,7,4.73,12-2015
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct Date
{
    int year;
    int month;
} Date;

typedef struct Book
{
    long long int isbn;
    char title[100];
    char author[100];
    int quantity;
    int price;
    Date date;
} Book;

int main() {
    Book* Books;
    int n_books=0;
    FILE *ptr = fopen("Books.txt", "r");

    if(ptr!=NULL) {
        Books = (Book*)malloc(sizeof(Book));

        while(!feof(ptr)) {

            fscanf(ptr,"%lld",&((*(Books n_books)).isbn));
            fscanf(ptr,"%s",(*(Books n_books)).title);
            fscanf(ptr,"%s",(*(Books n_books)).author);
            fscanf(ptr,"%d",&((*(Books n_books)).quantity));
            fscanf(ptr,"%f",&((*(Books n_books)).price));
            Date date;
            fscanf(ptr,"%d",&date.month);
            fscanf(ptr,"%d",&date.year);
            (*(Books n_books)).date = date;

            printf("Name:%s\n",Books[n_books].title);
            printf("ID:%lld\n",Books[n_books].isbn);
            printf("price:%f\n",Books[n_books].price);
            printf("date:%d-%d\n",Books[n_books].date.month,Books[n_books].date.year);
            printf("quantity:%d\n",Books[n_books].quantity);
            printf("author:%s\n",Books[n_books].author);

            n_books  ;
            Books=realloc(Books,sizeof(Book)*n_books);
        }

        fclose(ptr);
    }
    else {
        printf("Couldnt load books data");
        exit(0);
    }

    free(Books);
    return 0;
}

CodePudding user response:

Your program has the following issues:

  1. The %s conversion format specifier will only read a single word.
  2. You are using while(!feof(ptr)), which is generally wrong (and also wrong in this case).
  3. You are not skipping the , in the input stream.
  4. By using %f, you are telling fscanf to store a float into int price.
  5. The line Books=realloc(Books,sizeof(Book)*n_books); will only allocate enough memory for what you are currently using, but you need to allocate enough for what you are currently using AND for the next book.

Here is a solution which fixes these issues:

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

typedef struct Date
{
    int year;
    int month;

} Date;

typedef struct Book
{
    long long int isbn;
    char title[100];
    char author[100];
    int quantity;
    double price;
    Date date;

} Book;

int main( void )
{
    Book *Books;
    int n_books = 0;

    FILE *fp = fopen( "Books.txt", "r" );
    if ( fp == NULL )
    {
        perror( "fopen" );
        exit( EXIT_FAILURE );
    }

    Books = malloc( sizeof(Book) );
    if ( Books == NULL )
    {
        fprintf( stderr, "Memory allocation error!\n" );
        exit( EXIT_FAILURE );
    }

    while (
        fscanf(
            fp,
            "%lld,           
  • Related