GIDForums  

Go Back   GIDForums > Computer Programming Forums > C Programming Language
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

 
 
Thread Tools Search this Thread Rate Thread
  #1  
Old 24-Oct-2004, 13:50
The_Kingpin The_Kingpin is offline
New Member
 
Join Date: Oct 2004
Posts: 13
The_Kingpin is on a distinguished road

Problem reading structs in a file


Hi all, I have a file containing some info on separated lines, each six lines represent a struct. I'm trying to read these structs and put them in an array of structs so I can and print them after. Just wanted to get some feedback on my function, I'm still new and want some help before continuing. Thanks for your time

Here's what it looks like.

CPP / C++ / C Code:
#include "stdafx.h"
#include "stdio.h"
#include "stdlib.h"

struct book
	{
    char title[80];
    char autor[40];
    char editor[20];
    char ISBN[10];
    char subject[20];
    int release;
	};
typedef struct book bookInfo;


int main()
{
  char x[50];
  FILE *file; //file opened
  infoLivre *books; // array of struct of undefined length
  int num_books = 0;
  int i, j;

  file = fopen("books.txt", "r"); 
  if(file==NULL) {
    printf("Error: can't open file.\n");
    return 1; 
  }
  else {
    while (!feof(file)){ 

       if(num_books==0) {
        books = calloc(1, sizeof(infoLivre));
      }
      else {
        books = realloc(books, (num_books+1)*sizeof(bookInfo));
      }

      /* now try to store relevant info in our struct field.
         can do it character at a time as sscanf won't work as
         it falls apart with spaces between names               */

      for(i=0, j=0 ; c[i]!='\t' ; i++, j++) { 
        /* this keeps looping until a tab character is reached */
        books[num_books].title[j] = c[i];
      }

      /* add a null character to terminate string */
      books[num_books].title[j] = '\0';

      for(i++, j=0 ; c[i]!='\t' ; i++, j++) {
        books[num_books].autor[j] = c[i];
      }
      books[num_books].autor = '\0';


      for(i++, j=0 ; c[i]!='\0' && c[i]!='\n'; i++, j++) {
        /* store the gender but ignore the last newline character */
        books[num_books].editor[j] = c[i];
      }

      books[num_books].editor[j] = '\0';

      num_books++; /* keep track of how many we stored */
    }
    fclose(file); /* close file */

    /* print all the info */

    for(i=0 ; i<num_books; i++) { 
      printf("%s\t ", books[i].title);
      printf("%s\t ", books[i].autor);
      printf("%d\t\n", books[i].editor);
    }

    if(books!=NULL) {
      free(books);    /* free any allocated memory */
    }

    return 0;
  }
}
Last edited by JdS : 25-Oct-2004 at 06:10. Reason: Please insert your example C/C++ codes between [c] and [/c] tags
  #2  
Old 24-Oct-2004, 14:43
WaltP's Avatar
WaltP WaltP is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Midwest US
Posts: 3,245
WaltP is a name known to allWaltP is a name known to allWaltP is a name known to allWaltP is a name known to allWaltP is a name known to allWaltP is a name known to all
Quote:
Originally Posted by The_Kingpin
Hi all, I have a file containing some info on separated lines, each six lines represent a struct. I'm trying to read these structs and put them in an array of structs so I can and print them after. Just wanted to get some feedback on my function, I'm still new and want some help before continuing. Thanks for your time
Hey Kingpin, welcome to GID! We'll help if we can, but you have to make it easier on us

When posting, it helps to tell us what kind of feedback you want, many of us will have a field day ripping your code apart giving you no real help :-) So what type of feedback do you want? Does your code work? If not (and that's the feedback you want) you have to let us know what's wrong, where it's wrong, and what you think the problem is.

And I know somewhere on the site (maybe in a sticky?) there's an axplanation how to post code so it's readable. Therefore, my first "feedback" is:

Quote:
I can't read the code, it's unformatted. Use code tage to preserve your formatting!
__________________

Age is unimportant -- except in cheese
  #3  
Old 24-Oct-2004, 15:11
The_Kingpin The_Kingpin is offline
New Member
 
Join Date: Oct 2004
Posts: 13
The_Kingpin is on a distinguished road
Thanks Walt for not flamming me :-)

Right now the file is opened correctly and I'm able to read each line and print them in a new file. My problem is to insert each struc t(which iare made of 6 consecutive lines) as an item in my array.

CPP / C++ / C Code:
for(i=0, j=0 ; c[i]!='\t' ; i++, j++) { 
/* this keeps looping until a tab character is reached */
books[num_books].title[j] = c[i];
}

/* add a null character to terminate string */
books[num_books].title[j] = '\0';

When reading a line in the file books.txt, this is how I currently assign a value to a field of the struct infoBook. Then, when the struct is completed (with the 6 fields having value), I need to add this struct to the array books, which I'm not able right now :-? I'm not sure my structure is correct, but I tried regrouping all the info I learned so far...

Here's the complete code
CPP / C++ / C Code:
#include "stdafx.h"
#include "stdio.h"
#include "stdlib.h"

struct book
{
char title[80];
char autor[40];
char editor[20];
char ISBN[10];
char subject[20];
int release;
};
typedef struct book bookInfo;


int main()
{
char x[50];
FILE *file; //file opened
infoLivre *books; // array of struct of undefined length
int num_books = 0;
int i, j;

file = fopen("books.txt", "r"); 
if(file==NULL) {
printf("Error: can't open file.\n");
return 1; 
}
else {
while (!feof(file)){ 

if(num_books==0) {
books = calloc(1, sizeof(infoLivre));
}
else {
books = realloc(books, (num_books+1)*sizeof(bookInfo));
}

/* now try to store relevant info in our struct field.
can do it character at a time as sscanf won't work as
it falls apart with spaces between names */

for(i=0, j=0 ; c[i]!='\t' ; i++, j++) { 
/* this keeps looping until a tab character is reached */
books[num_books].title[j] = c[i];
}

/* add a null character to terminate string */
books[num_books].title[j] = '\0';

for(i++, j=0 ; c[i]!='\t' ; i++, j++) {
books[num_books].autor[j] = c[i];
}
books[num_books].autor = '\0';


for(i++, j=0 ; c[i]!='\0' && c[i]!='\n'; i++, j++) {
/* store the gender but ignore the last newline character */
books[num_books].editor[j] = c[i];
}

books[num_books].editor[j] = '\0';

num_books++; /* keep track of how many we stored */
}
fclose(file); /* close file */

/* print all the info */

for(i=0 ; i<num_books; i++) { 
printf("%s\t ", books[i].title);
printf("%s\t ", books[i].autor);
printf("%d\t\n", books[i].editor);
}

if(books!=NULL) {
free(books); /* free any allocated memory */
}

return 0;
}
}
Last edited by dsmith : 24-Oct-2004 at 15:47. Reason: Use [c] & [/c] for c syntax not [code]
  #4  
Old 24-Oct-2004, 18:01
nkhambal nkhambal is offline
Regular Member
 
Join Date: Jul 2004
Location: CA USA
Posts: 313
nkhambal is a jewel in the roughnkhambal is a jewel in the rough
what is the definition of array "c". I don't see it declared anywhere in the code. Also, is "infoLivre" of same type as "bookInfo" ?. You are mallocing memory of size "infoLivre" and reallocing of size "bookInfo". I don't see a code line for reading the line from file. How you are getting values from file?

Am i missing here something?

Can you pls post reply to these queries to better understand your code.

Also, pls use code tags when posting your code.

Thanks,
  #5  
Old 24-Oct-2004, 18:16
The_Kingpin The_Kingpin is offline
New Member
 
Join Date: Oct 2004
Posts: 13
The_Kingpin is on a distinguished road
Quote:
Originally Posted by nkhambal
what is the definition of array "c". I don't see it declared anywhere in the code. Also, is "infoLivre" of same type as "bookInfo" ?. You are mallocing memory of size "infoLivre" and reallocing of size "bookInfo". I don't see a code line for reading the line from file. How you are getting values from file?

Am i missing here something?

Can you pls post reply to these queries to better understand your code.

Also, pls use code tags when posting your code.

Thanks,

Livres = Books, I translates all my code so I might have forgotten to change certain word.

Also, the declaration is

char c[50]; and not x, I used it to test and post the old one, sorry

:-?

Thanks for your help
  #6  
Old 24-Oct-2004, 22:46
nkhambal nkhambal is offline
Regular Member
 
Join Date: Jul 2004
Location: CA USA
Posts: 313
nkhambal is a jewel in the roughnkhambal is a jewel in the rough
you haven't yet explained how are you fetching data from the file. I guess you either forgot to code it or you forgot to paste it in your post.

whichever it is, you still need a code line to fetch data from file. I would suggest (if you have not already coded it) use fgets() and sscanf() conbination to read words from file.
  #7  
Old 25-Oct-2004, 01:55
WaltP's Avatar
WaltP WaltP is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Midwest US
Posts: 3,245
WaltP is a name known to allWaltP is a name known to allWaltP is a name known to allWaltP is a name known to allWaltP is a name known to allWaltP is a name known to all
Quote:
Originally Posted by The_Kingpin
Thanks Walt for not flamming me :-)
You're welcome. My "flame Management" group seems to be working. I've memorized their 12 step pattern

Quote:
Originally Posted by The_Kingpin
CPP / C++ / C Code:
while (!feof(file)){ 
The feof() function should not be used to test for eof in a loop. You may see problems when you reach the end of the file. Use the return values from your read statement.

Also, code tags are only useful for keeping your formatting intact so your post can be read. But if you have no formatting, they really are useless. You might want to read this tutorial for the hows and whys of formatting. You're writing long enough code that it's already important to get in the habit.

By the way, aren't instructors going over formatting code these days? If not, could you ask yours "why not?" I'm very interested why this important step is being left out of the training.
__________________

Age is unimportant -- except in cheese
  #8  
Old 25-Oct-2004, 08:07
The_Kingpin The_Kingpin is offline
New Member
 
Join Date: Oct 2004
Posts: 13
The_Kingpin is on a distinguished road
Ok post the function the parse each line into a struct, which will be add to an array of struct once it is complete. I try adding some things I found on the web since I'm still new to C.

Currently I have 2 problem when compiling:
-"BOOK book;"
-"books[num_books] = book;"

I thought we could declare a new instance of a struct in the function but it gives me the "Undeclared identifier"...

The other error says "cannot convert from int to bookInfo", but I'm trying to assign a value from a struct book to the num_books value of the struct array, which is a struct... :-?

Any help would be appreciate. Thanks

Code:
#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; // Array of books, UNKNOWN size ! char *buff; // Buffer to read in the file int num_books = 0; // Keep the count of number read in int i, j; /* 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 */ { BOOK book; /*read a line and put it in the struct */ if(parseline(&book, buff) == 0) { books = realloc(books, (num_books + 1) * sizeof(BOOK)); if(!books) { /* out of memory, bale */ books[num_books] = book; num_books++; } } } } // 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 puts it in an array */ int parseline(BOOK *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; }
  #9  
Old 25-Oct-2004, 13:04
nkhambal nkhambal is offline
Regular Member
 
Join Date: Jul 2004
Location: CA USA
Posts: 313
nkhambal is a jewel in the roughnkhambal is a jewel in the rough
Here are few comments about your code. They are in no specific order. These are not exhaustive comments. Other might come up with more.

1. You can not use "buf" without allocating memory to it. Since buf is a un initialized pointer, it does not point to any allocated memory location. Your program will crash at fgets().

2. Secondly, Do you mean same when you type BOOK and book? . They are not same. BOOK is different than book. There is no definition for BOOK in your code. Your compiler will flags error as unknown storage type.

3. Following lines
CPP / C++ / C Code:
books = realloc(books, (num_books + 1) * sizeof(BOOK));
             if(!books)

should be changed to
CPP / C++ / C Code:
books = realloc(books, (num_books + 1) * sizeof(book));
             if(books==NULL)

4. You should check of EOF and not NULL in following line of code.
CPP / C++ / C Code:
while(fgets(buff, sizeof(buff), file) != NULL)
it should be
CPP / C++ / C Code:
while(fgets(buff, sizeof(buff), file) != EOF)

5. This line is wrong as there is no storage defined by name BOOK and book is already a defined structure.
CPP / C++ / C Code:
BOOK book;

6. If you want to setup up a dynamic storage of books. You need to define a linked list where each node (a book entry) will hold the address of next node. Books needs to added and removed to dynamic linked list. You are mixing stating and dynamic storage. You are not linking the books. They are scattered all over your memory and may not be in contiguous blocks of memory, cuase you are dynamiclly allocating the storage for book using malloc() and reallloc(). Pls read about linked lists to build this type of dynamic storages.

For starters, I can give you a code to modify your structure book to make a linked list. In below code, pointer variable next of type struct book, points to the next memory location where the next book entry is stored.

CPP / C++ / C Code:
struct book
{
    char title[80];
    char autor[40];
    char editor[20];
    char ISBN[10];
    char subject[20];
    int releaseDate;
    struct book *next;     //Points to next book in the list.
};

so finally your book list should look like.
CPP / C++ / C Code:
(book1)(book1->next)--->(book2)(book2->next)--->.......(bookn)(bookn->next=NULL)

where book1 is first node in list and bookn is last node.

My 2 cents.
  #10  
Old 25-Oct-2004, 17:19
The_Kingpin The_Kingpin is offline
New Member
 
Join Date: Oct 2004
Posts: 13
The_Kingpin is on a distinguished road
Quote:
6. If you want to setup up a dynamic storage of books. You need to define a linked list where each node (a book entry) will hold the address of next node. Books needs to added and removed to dynamic linked list.

Ok I'll try using linked lists even if I haven't see them in class yet. If anyone could set me on the right track that would be very appreciated. BTW can we defined a new struct directly in a function ? See below

CPP / C++ / C Code:
 #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 */
   char count;
   char Book;
   char Author;
   char Editor;
   char ISBN;
   char Subject;
   char releaseDate;
 
   /* First step we open the file and see if it's correct */
   file = fopen("livres.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 */
				count = fscanf (file,"%s\n%s\n%s\n%s\n%s\n%s\n", &Book, &Author, &Editor, &ISBN, &Subject, &releaseDate);

				typedef struct
				{
				char *title;
				char *author;
				char *editor;
				char *isbn;
				char *subject;
				char *releaseDate;
				next *Book_t;
				}  Book_t;

				Book_t *MyBook;

				MyBook = (Book_t *)malloc (sizeof (Book_t));
				MyBook->title = strdup (Book);
				MyBook->author = strdup (Author);
				MyBook->editor = strdup (Editor);
				MyBook->isbn = strdup (ISBN);
				MyBook->subject = strdup (Subject);
				MyBook->releaseDate = strdup (releaseDate);
				
				books[num_books] = MyBook; /* 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;
 }
 
 

Recent GIDBlogPython ebook by crystalattice

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
CD burner wont burn!! robertli55 Computer Hardware Forum 1 18-Jun-2004 10:53
Yet another CD burner problem: Lite-On LSC-24082K Erwin Computer Hardware Forum 1 22-May-2004 11:28
Re: Programming Techniques WaltP C Programming Language 0 09-Mar-2004 23:56
reading and writing to a file in C++ mgp6q C++ Forum 17 02-Mar-2004 12:42

Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The

All times are GMT -6. The time now is 20:58.


vBulletin, Copyright © 2000 - 2008, Jelsoft Enterprises Ltd.