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
  #11  
Old 25-Oct-2004, 18:56
nkhambal nkhambal is offline
Regular Member
 
Join Date: Jul 2004
Location: CA USA
Posts: 315
nkhambal is a jewel in the roughnkhambal is a jewel in the rough
My intension was not to force you to use linked list. If you haven't yet learned it in your class, in this program you can use static storage such as arrays. Infact that would be a good way to start.

Again in your new post there are several mistakes.

in fscanf you are collecting strings in single characters
CPP / C++ / C Code:
fscanf (file,"%s\n%s\n%s\n%s\n%s\n%s\n", &Book, &Author, &Editor, &ISBN, &Subject, &releaseDate);

all the variables you are supplying above are defined as char which will hold only 1 byte and can not hold strings.

also, you do not need & operater when you are collecting string using an array of chars. Following statement is valid provided you change all your variables to either char array or char pointers.

CPP / C++ / C Code:
fscanf (file,"%s\n%s\n%s\n%s\n%s\n%s\n", Book, Author, Editor, ISBN, Subject, releaseDate);

Secondly,to answer your question, Yes, you can define a structure inside a function. However, beware that its scope is limited to that function. If you wanna define a new storage type, its better you do it globally so that any function in the source file can use the storage definition to define new variables of that type.

There is one problem here in your structure definition inside main()
I am just correcting it, leaving the understanding part to you.
CPP / C++ / C Code:
typedef struct 
        {
        char *title;
        char *author;
        char *editor;
        char *isbn;
        char *subject;
        char *releaseDate;
        Book_t *next;
        }  Book_t;

Finally, not trying to discourage you but, I would suggest you not to directly jump into pointers and linked list. Get this program work with simple static storage for everything. This will also help you in eliminating all syntax related errors in your code. If you want to learn about linked list, there are some tutorials in this forum on that. You can also use following link.

http://juicystudio.com/tutorial/c/linked.asp

Good Luck,
  #12  
Old 25-Oct-2004, 19:52
The_Kingpin The_Kingpin is offline
New Member
 
Join Date: Oct 2004
Posts: 13
The_Kingpin is on a distinguished road
thanks nkhambal, I'll read the tutorial.

I thought using linked lists would be easier, but I'll go with static storage like you said since I do nothave all the knowledge yet.

Now I can read each line of my file and separate groups of 6 line to create struct, but somehow my buffer is confused and I get only half-word :-?

I used a switch to manage the linformation I get from the file depending on it's line_number. This way a line #1 is aadded to the record #1 of a struct.

I also think I have a problem with my array books which is supposed to contain every struck (book or group of 6 lines) because when I use books(value) it doesn't return me what it is supposed to... Thanks for all your help guys, I wish I can finish this by tonight

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];
     char releaseDate[10];
 };
 typedef struct book bookInfo;


  /* Function that reads the current line of the file and creates struct */
int parseline(bookInfo *out, const char *str, int line_num)
{
  int i;

  switch(line_num)
	{
	case 0:
			/* TITLE RECORD */
			/* stop on tab, but also on end of string or overflow so we don't crash */
			for(i=0; str[i] != '\t' && str[i] != '\n' && i < 63;i++)
				out->title[i] = str[i];

				/* return -1 on parse error */
				if(str[i] != '\t')
				return -1;

				/* for convenience, move the pointer along for the next field */
				str += i +1;
			break;

	case 1:
			/* AUTHOR RECORD */
			/* stop on tab, but also on end of string or overflow so we don't crash */
			for(i=0; str[i] != '\t' && str[i] != '\n' && i < 63;i++)
				out->autor[i] = str[i];

				/* return -1 on parse error */
				if(str[i] != '\t')
				return -1;

				/* for convenience, move the pointer along for the next field */
				str += i +1;
				break;

	case 2:
			/* EDITOR RECORD */
			/* stop on tab, but also on end of string or overflow so we don't crash */
			for(i=0; str[i] != '\t' && str[i] != '\n' && i < 63;i++)
				out->editor[i] = str[i];

				/* return -1 on parse error */
				if(str[i] != '\t')
				return -1;

				/* for convenience, move the pointer along for the next field */
				str += i +1;
				break;

	case 3:
			/* ISBN RECORD */
			/* stop on tab, but also on end of string or overflow so we don't crash */
			for(i=0; str[i] != '\t' && str[i] != '\n' && i < 63;i++)
				out->ISBN[i] = str[i];

				/* return -1 on parse error */
				if(str[i] != '\t')
				return -1;

				/* for convenience, move the pointer along for the next field */
				str += i +1;
				break;

	case 4:
			/* SUBJECT RECORD */
			/* stop on tab, but also on end of string or overflow so we don't crash */
			for(i=0; str[i] != '\t' && str[i] != '\n' && i < 63;i++)
				out->subject[i] = str[i];

				/* return -1 on parse error */
				if(str[i] != '\t')
				return -1;

				/* for convenience, move the pointer along for the next field */
				str += i +1;
				break;

	case 5:
			/* releaseDate RECORD */
			/* stop on tab, but also on end of string or overflow so we don't crash */
			for(i=0; str[i] != '\t' && str[i] != '\n' && i < 63;i++)
				out->releaseDate[i] = str[i];

				/* return -1 on parse error */
				if(str[i] != '\t')
				return -1;

				/* for convenience, move the pointer along for the next field */
				str += i +1;
				break;
	}
  /* 0 to indicate OK */
  return 0;
}
 
 
 int main()
 {
   FILE *file;                 // File containing the data
   bookInfo *books = NULL;     // Array of books, UNKNOWN size 
   char buff[1000];         // Buffer to read in the file
   int i;
   int num_books = 0;          // Keep the count of number read in
   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("livres.txt", "r");
   if(file==NULL)
      {
      printf("Error: can't open file.\n");
      return 1;
      }
   else
      {
	  /* First loop tthat goes through every line of the file */
      while(fgets(buff, sizeof(buff), file) != NULL)
        {
			bookInfo BOOK;
			/* Resize the array containing the structs */
			void *temp = realloc( books, (num_books + 1) * sizeof(bookInfo));
			if ( temp != NULL ) 
			  {
			    books = temp;
				
			    /* Creation of the struct */
			    if(parseline(&BOOK, buff, line_number) == 0)
				  {
				  books = realloc(books, (num_books + 1) * sizeof(bookInfo));
				  }
			   }
			
			if(line_number==6)
				{
				books[num_books] = BOOK; /* 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
				line_number=0; // Reset the line number so we can create a new struct
				}

			line_number++;
			fgets(buff, sizeof(buff+1), file);
		 }
	  } // 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;
 }
  #13  
Old 25-Oct-2004, 20:53
nkhambal nkhambal is offline
Regular Member
 
Join Date: Jul 2004
Location: CA USA
Posts: 315
nkhambal is a jewel in the roughnkhambal is a jewel in the rough
Can you show us how you have arranged data in your text file. ? Post one entry for full record(all members of structure) in the way it is stored in file.

Also, I still see you mixing dynamic storage with static. I would recommend stick to static for now. Define static variables instead of char * and avoid mallocs and reallocs. Its unncessarily complicating a simple things. Onces it works fine with static storage, you can think of migrating or optimizing it with dynamic storages using pointers and linked list.
  #14  
Old 25-Oct-2004, 21:29
The_Kingpin The_Kingpin is offline
New Member
 
Join Date: Oct 2004
Posts: 13
The_Kingpin is on a distinguished road
This is an example of what should give 2 struct

The Big Bang
GRIBBIN, JOHN
FLAMMARION
208081270X
Science
10/6/1992
The Bits
RUSSELL BERTRAND
UNION GEN. D'ED.
2264025751
Computers
4/3/1997


keep in mind that they are always in this order
Title
Author
Editor
ISBN (code)
Subject
Release date


Hope its help. Frank
  #15  
Old 25-Oct-2004, 22:37
WaltP's Avatar
WaltP WaltP is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Midwest US
Posts: 3,335
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
This is an example of what should give 2 struct

The Big Bang
GRIBBIN, JOHN
FLAMMARION
208081270X
Science
10/6/1992
The Bits
RUSSELL BERTRAND
UNION GEN. D'ED.
2264025751
Computers
4/3/1997


keep in mind that they are always in this order
Title
Author
Editor
ISBN (code)
Subject
Release date


Hope its help. Frank

The statement
CPP / C++ / C Code:
str += i +1;
should be removed. You do not want to move the pointer and the index. What you have is
Code:
i char from str 1 1st 2 3rd 3 6th 4 10th 5 15th and so on


This segment of code should cause you no end of headaches:
CPP / C++ / C Code:
      void *temp = realloc( books, (num_books + 1) * sizeof(bookInfo));
      if ( temp != NULL ) 
        {
          books = temp;
        
          /* Creation of the struct */
          if(parseline(&BOOK, buff, line_number) == 0)
          {
          books = realloc(books, (num_books + 1) * sizeof(bookInfo));
          }
         }
Here you:
1) make books bigger and assign the address to temp
2) reassign the pointer in tempback to books
3) then allocate yet another entry in books

Instead of all these memory gyrations, simply define the books array to handle twice the data in your file and get rid of all memory allocations. You're getting too complicated for a beginner and don't yet have the techniques down for this higher level concepts. And you don't need temp at all.


And:
CPP / C++ / C Code:
        books[num_books] = BOOK; /* 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 */
C does not allow you to use = on two structs. You must use either
1) a function to move the entries from one to the other
2) use memcpy() to move all the bytes from one to the other


Then
CPP / C++ / C Code:
    /* First loop tthat goes through every line of the file */
      while(fgets(buff, sizeof(buff), file) != NULL)
        {
      bookInfo BOOK;
...
      line_number++;
      fgets(buff, sizeof(buff+1), file);
     }
Here you
1) read line 1 in the while statement
2) process the line
3) read line 2 at the bottom of the while
4) read line 3 in the while statement
so you are only processing every other line from the file.


This should keep you busy, along with what nkhambal said above.

Also, you know that when you say:
CPP / C++ / C Code:
char date[10];
your date field is only 9 characters long, don't you? You must always leave 1 final character for the ending '\0' if these values are strings.
__________________

During the election they said Obama could only be elected when pigs fly. Well, we currently have an epidemic of Swine Flu. Coincidence?
  #16  
Old 26-Oct-2004, 00:34
nkhambal nkhambal is offline
Regular Member
 
Join Date: Jul 2004
Location: CA USA
Posts: 315
nkhambal is a jewel in the roughnkhambal is a jewel in the rough
Hi kingpin,

I hate to do this but since i see you struggling with this code, here is the code that I worked on. Its with static storage (array). This works fine. This will give you some idea and baseline to work on if you wan to work on it with linked list.

CPP / C++ / C Code:
#include <stdio.h>

struct book
 {
     char title[80];
     char author[40];
     char editor[20];
     char ISBN[20];
     char subject[20];
     char releaseDate[10];
 };
 typedef struct book bookInfo;

int main(int argc, char *argv[])
{
	bookInfo books[100];
	int record_count=0;
	int i;
	FILE *fp;

	if ((fp=fopen("data.txt","r"))==NULL)
	{
		printf("\nFile open error\n");
		exit(0);
	}

		while (!feof(fp))
		{
			
			
			getline(books[record_count].title,fp);
			getline(books[record_count].author,fp);
			getline(books[record_count].editor,fp);
			getline(books[record_count].ISBN,fp);
			getline(books[record_count].subject,fp);
			getline(books[record_count].releaseDate,fp);
			record_count++;
		}
	
	for (i=0;i<record_count-1;i++)
	{
		printf("%s\n",books[i].title);
		printf("%s\n",books[i].author);
		printf("%s\n",books[i].editor);
		printf("%s\n",books[i].ISBN);
		printf("%s\n",books[i].subject);
		printf("%s\n",books[i].releaseDate);
	}
return 0;
}

getline(char *str, FILE *fp)
{
	char ch;
	int i=0;
	while ((ch=(char)fgetc(fp))!='\n'  && (ch!=EOF) && (ch!='\r'))
	{
		str[i]=ch;
		i++;
	}
	str[i]='\0';
}

Good Luck.
  #17  
Old 27-Oct-2004, 00:07
WaltP's Avatar
WaltP WaltP is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Midwest US
Posts: 3,335
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 nkhambal
Hi kingpin,

I hate to do this but since i see you struggling with this code, here is the code that I worked on. Its with static storage (array). This works fine. This will give you some idea and baseline to work on if you wan to work on it with linked list.

CPP / C++ / C Code:
...
while (!feof(fp))
...
getline(char *str, FILE *fp)
{
	char ch;
	int i=0;
	while ((ch=(char)fgetc(fp))!='\n'  && (ch!=EOF) && (ch!='\r'))
	{
		str[i]=ch;
		i++;
	}
	str[i]='\0';
}

Good Luck.
I hate for you to do it too....

As I've said elsewhere, never Never NEVER NEVER use feof() to test for the end of file to terminate a loop. It will usually fail because it will not return TRUE until after (not when but AFTER) the end of file is reached -- which means you will get one bogus record.

And instead of reading a character at a time, read an entire line with fgets(). Most of your getline() routine can be changed to
CPP / C++ / C Code:
int bytes;
bytes = fgets(str, MAXCHRS, fp);
From here simply remove the '\n' at the end of str using strlen() and return bytes, which will be EOF if you are at EOF.

Also, you did not specify a type for getline(). By default you've defined it as an int so you need to return an int to the calling function.
__________________

During the election they said Obama could only be elected when pigs fly. Well, we currently have an epidemic of Swine Flu. Coincidence?
 
 

Recent GIDBlogOnce again, no time for hobbies 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 11:53
Yet another CD burner problem: Lite-On LSC-24082K Erwin Computer Hardware Forum 1 22-May-2004 12:28
Re: Programming Techniques WaltP C Programming Language 0 10-Mar-2004 00:56
reading and writing to a file in C++ mgp6q C++ Forum 17 02-Mar-2004 13:42

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

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


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