• C

Question about Static and Dynamic storage when reading struct from a file

Hi all, thanks to your advices I was able to correct my previous problem.

Now I have other issues with my code and the thinking behind it. I need to read 6 consecutive lines (which represent are always in the correct order and are informations on a book) of a file and use them to create a new struct (which is the book). Once the struct is made, it must be added to an array containing every struct (book).

I was wondering what was the best way to do this. Right now I dont use linked lists but I thought this might be a reason of my problem.
I also wanted to know if I needed read all the informations into a temporary book, and then assign it to my array when I'm done with it.

Thanks a lot for your time.

Here my code for consutlation:

#include "stdafx.h"
#include "stdio.h"
#include <stdlib.h>
 /* Struct containing the informations on a book */
 struct book
     char title[80];
     char autor[40];
     char editor[20];
     char ISBN[10];
     char subject[20];
     int  releaseDate;
 typedef struct book bookInfo;
 int main()
   char c[50];                          // Store line we read
   FILE *file;                           // File containing the data
   bookInfo *books = NULL;     // Array of books, UNKNOWN size
   char buff[1000];                 // Buffer to read in the file
   int num_books = 0;            // Keep the count of number read in
   int i, j;
   int line_number = 0;        /* Used to count the 6 lines required to create a new struct */
   /* First step we open the file and see if it's correct */
   file = fopen("books.txt", "r");
      printf("Error: can't open file.\n");
      return 1;
      while(fgets(buff, sizeof(buff), file) != NULL)  /* Loop until there's nothing to read*/
        /*read a line and put it in the struct */
            void *temp = realloc( books, (num_books + 1) * sizeof(bookInfo));
            if ( temp != NULL )
                books = temp; // Set the correct size of the array containing structs
                /* We loop until there's 6 lines added to the struct bookInfo */
                for(line_number=0; line_number<=6; line_number++)
                {int parseline(bookInfo *out, const char *str);}
                books[num_books] = bookInfo; /* We add the new book (bookInfo) in the array of struct
                                            at the correct position only when all the fields of the
                                            struct are full */

                num_books++; // Increase the number of line read
        } // end else
     fclose(file); /* close file */
     for(i=0 ; i<num_books; i++)
       printf("%s\t ", books[i].title);
       //printf(every other fields of the struct....)
       free(books);    /* free any allocated memory */
     return 0;
 /* Function that reads the current line of the file and creates struct */
 int parseline(bookInfo *out, const char *str)
   int i;
   /* stop on tab, but also on end of string or overflow so we don't crash*/
   for(i=0; str[i] != '\t' && str[i] != 0 && i < 63;i++)
      out->title[i] = str[i];
      out->title[i] = 0;
   /* return -1 on parse error */
   if(str[i] != '\t')
   return -1;
   /* for convenience, move the pointer along for the next field */
   str += i +1;
   /* now do the same thing for the other fields */
   /* 0 to indicate OK */
   return 0;
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Kent OlsenData Warehouse Architect / DBACommented:
Hi The_Kingpin08,

You've got lots of options here, and which one you choose will depend on your requirements.

Arrays are the easiest.  They program the quickest and offer fewer debugging issues.  If you know the limits of your data this can be a very effective solution.

Linked lists offer the most flexibility.  If you don't know the contents of the data, or it changes during the programs execution, linked lists are probably the right choice.  They also provide the most memory-friendly solution.

To read all of the data from a file, use fscanf().  It's the most versatile, and will let you "condense" 6 read statements into one.  (Note that this is an example format string!)

  count = fscanf ("%s\n%s\n%s\n%s\n%s\n%s\n", &Book, &Author, &Line3, &Line4, &Line5, &Line6);

And then define a structure that is a series of pointers:

typedef struct
  char *Title;
  char *Author;
  char *Line3;
  char *Line4;
  char *Line5;
  char *Line6;
  next *Book_t;
}  Book_t;

After reading the book info from the file, simply make a structure and add the data.

Book_t *MyBook;

  MyBook = (Book_t *)malloc (sizeof (Book_t));
  MyBook->Title = strdup (Book);
  MyBook->Author = strdup (Author);
  MyBook->Line3 = strdup (Line3);

And then just link the structure into your Book chain.

All done!

Good Luck!

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
The_Kingpin08Author Commented:
Can I define a new struct directly in the main function or this would require me to create a new function and call it with parameters ?

BTW I find your idea really genius because it's way more simple then what I was trying to do. I should have started with that because life became so complicated for nothing...

Thanks a lot
Kent OlsenData Warehouse Architect / DBACommented:
Hi The_Kingpin08,

You can define a struct anywhere that you want to, with a couple of gotchas.  They need to be defined at a global level.  That is, put their definition between functions, not within one.  The function definition holds for all of the subsequent source, including source that is inserted via #include.

#include <file1.h>

int Function1 ()
  return 0;

struct MyStruct

#include <file2.h>

int Function2 ()
  return 1;

In this example, MyStruct can be used in Function2, within file2.h, AND within anything that file2.h #includes.

It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.