Solved

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

Posted on 2004-10-25
275 Views
Last Modified: 2010-04-15
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");
   if(file==NULL)
      {
      printf("Error: can't open file.\n");
      return 1;
      }
   else
      {
      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....)
     }
 
     if(books!=NULL)
     {
       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;
 }
0
Question by:The_Kingpin08
    3 Comments
     
    LVL 45

    Accepted Solution

    by:
    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);
      etc...

    And then just link the structure into your Book chain.

    All done!


    Good Luck!
    Kent
    0
     

    Author Comment

    by:The_Kingpin08
    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
    0
     
    LVL 45

    Assisted Solution

    by:Kdo
    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.


    Kent
    0

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    How your wiki can always stay up-to-date

    Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
    - Increase transparency
    - Onboard new hires faster
    - Access from mobile/offline

    Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
    This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
    The goal of this video is to provide viewers with basic examples to understand recursion in the C programming language.
    Video by: Grant
    The goal of this video is to provide viewers with basic examples to understand and use while-loops in the C programming language.

    913 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    15 Experts available now in Live!

    Get 1:1 Help Now