Thread: I need help on this particular Linked List problem

  1. #1
    and Nothing Else Matters
    Join Date
    Jul 2006
    Location
    Philippines
    Posts
    117

    I need help on this particular Linked List problem

    I have three functions which do three things:
    1.) It writes the element of a linked list (which is of type struct) into a file
    2.) It reads the same file and stores its contents into a linked list.
    3.) It prints the contents of the linked list.

    Code:
    typedef struct prod_record {
    	int prod_no;
    	char prod_name[50];
    	float price, stock_on_hand;
    }elementtype;
    
    typedef struct linked_list {
    	elementtype element;
    	struct linked_list *next;
    }list;
    
    typedef list *position;
    typedef list *list_ptr;
    
    void writeFile (list_ptr L)
    {
    	position p=L;
    	FILE *fp;
    
    	if ((fp=fopen("product.dat","wb")) == NULL)
    	{
    		printf ("\n\tUnable to open\n");
    		exit(1);
    	}
    
    	while (p != NULL)
    	{
    		fwrite (&(p->element), sizeof(elementtype), 1, fp);
    		p=p->next;
    	}
    	fclose(fp);
    }
    
    void readFile (list_ptr *L)
    {
    	FILE *fp;
    	position p,temp;
    	*L=NULL;
    	if ((fp=fopen("product.dat","rb")) != NULL)
    	{
    		while (!feof(fp))
    		{
    			temp=(position)malloc(sizeof(list));
    			fread (&(temp->element), sizeof(elementtype),1,fp);
    			if (*L == NULL)
    				*L=temp;
    			else
    				p->next=NULL;
    			p=temp;
    		} /* end while */
    
    		p->next=NULL;
    		fclose (fp);
    	} /*end if */
    	else
    		printf ("\n\tUnable to open file\n");
    } /*end read File */
    
    void printList (list_ptr L)
    {
    	position p=L;
    	if (p == NULL)
    		printf ("List empty\n");
    	while (p != NULL)
    	{
    		printf ("Product Number: %d\n", p->element.prod_no);
    		printf ("Product Name  : ");
    		puts (p->element.prod_name);
    		printf ("Price         : %.2f\n",p->element.price);
    		printf ("Stock-on-hand : %.2f\n",p->element.stock_on_hand);
    		getch();
    		p=p->next;
    	}
    }
    ---------------------------------------------------
    my problem is that when i call printList, only one element (the first struct) gets printed out. Can anyone trace my functions and tell me where i went wrong? thanks!!!

    note after writing 3 times, i saw that the file is 180bytes in size. it coincides with the fact that each record is supposed to be 60bytes long (2 bytes int, 50 bytes char[50], 8 bytes for the 2 floats.)

    so it must be somewhere on the readFile or printList. thanks!!

  2. #2
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    I don't suppose you could post the whole code -- headers and main and all?
    And post a sample of "product.dat" if you really want folks to be able to play along.
    Code:
    while (!feof(fp))
    And visit the FAQ:
    FAQ > Explanations of... > Why it's bad to use feof() to control a loop

    And check return values.
    Code:
    temp=(position)malloc(sizeof(list));
    Since this is the C Board, don't cast malloc.
    FAQ > Explanations of... > Casting malloc

    Code:
    typedef list *list_ptr;
    And typdef'ing pointers is evil!
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  3. #3
    and Nothing Else Matters
    Join Date
    Jul 2006
    Location
    Philippines
    Posts
    117
    Ok.. here is the entire code, with main and all...

    btw, im sorry for the feof and typecasting of malloc.. this wuz what i was taught at our school.. that's why im asking you guys becoz u seem to know more..

    Code:
    				 /* SINGLY LINKED LIST WITHOUT HEADER CELL */
    /*Write functions that deletes the passed product number when found in the*/
    /*prints all the elements in the list, deletes all the contents in the list;*/
    /*and locates and displays the information of prod no x.*/
    /*Input first*/
    /*The functions writeFile and readFile will write the information into a file,*/
    /*and retrieves the information saved*/
    
    #include <stdio.h>
    #include <conio.h>
    #include <stdlib.h>
    
    typedef struct prod_record {
    	int prod_no;
    	char prod_name[50];
    	float price, stock_on_hand;
    }elementtype;
    
    typedef struct linked_list {
    	elementtype element;
    	struct linked_list *next;
    }list;
    
    typedef list *position;
    typedef list *list_ptr;
    
    void deleteElement (int x, list_ptr *L);
    void insert (position x, int p, list_ptr *L);
    void printList (list_ptr L);
    void makeNull (list_ptr *L);
    void locate (int x, list_ptr *L);
    void writeFile (list_ptr L);
    void readFile (list_ptr *L);
    
    void main (void)
    {
    	list_ptr A;
    	int choice, temp_prod_no;
    	int p;
    	position x;
    
    	A=NULL;
    	printf ("M E N U : \n");
    	printf ("1.Insert Element\t2.Delete Element\t3.Print the contents\n");
    	printf ("4.Make Null\t\t5.Locate\t\t6.Write File\n7.Read File\t\t8.Quit\n");
    	printf ("\tChoice: ");
    	scanf ("%d",&choice);
    
    	while (choice > 0 && choice < 8)
    	{
    		if (choice == 1)
    		{
    			printf ("Enter the position you want to insert: ");
    			scanf ("%d",&p);
    			flushall();
    			x=(list_ptr)malloc(sizeof(list));
    			printf ("Enter the product number: ");
    			scanf ("%d",&x->element.prod_no);
    			printf ("Enter product name: ");
    			scanf ("%s",&x->element.prod_name);
    			printf ("Price: ");
    			scanf ("%f",&x->element.price);
    			printf ("Stock-on-hand: ");
    			scanf ("%f",&x->element.stock_on_hand);
    			x->next=NULL;
    			insert (x,p,&A);
    		}
    		else if (choice == 2)
    		{
    			printf ("Enter the product number you want to delete: ");
    			scanf ("%d",&temp_prod_no);
    			deleteElement(temp_prod_no,&A);
    		}
    		else if (choice == 3)
    		{
    			printList (A);
    		}
    		else if (choice == 4)
    		{
    			makeNull(&A);
    		}
    		else if (choice == 5)
    		{
    			printf ("Product number you want to display its information: ");
    			scanf ("%d",&temp_prod_no);
    			locate (temp_prod_no,&A);
    		}
    		else if (choice == 6)
    		{
    			writeFile (A);
    		}
    		else if (choice == 7)
    		{
    			readFile (&A);
    		}
    
    		getch();
    		clrscr();
    		printf ("M E N U : \n");
    		printf ("1.Insert Element\t2.Delete Element\t3.Print the contents\n");
    		printf ("4.Make Null\t\t5.Locate\t\t6.Write File\n7.Read File\t\t8.Quit\n");
    		printf ("\tChoice: ");
    		scanf ("%d",&choice);
    	}
    }
    
    void deleteElement (int x, list_ptr *L)
    {
    	position p,q;
    
    	if (*L == NULL)
    		printf ("\n\tList empty\n");
    	else if ((*L)->element.prod_no == x)
    	{
    		p=*L;
    		*L=p->next;
    		free(p);
    	}
    	else
    	{
    		for (p=*L; p != NULL && p->next->element.prod_no != x; p=p->next)
    			;
    		if (p->next->element.prod_no == x)
    		{
    			q=p->next;
    			p->next=q->next;
    			free(q);
    		}
    		else
    			printf ("\n\tNot found\n");
    	}
    }
    
    void writeFile (list_ptr L)
    {
    	position p=L;
    	FILE *fp;
    
    	if ((fp=fopen("product.dat","wb")) == NULL)
    	{
    		printf ("\n\tUnable to open\n");
    		exit(1);
    	}
    
    	while (p != NULL)
    	{
    		fwrite (&(p->element), sizeof(elementtype), 1, fp);
    		p=p->next;
    	}
    	fclose(fp);
    }
    
    void printList (list_ptr L)
    {
    	position p=L;
    	if (p == NULL)
    		printf ("List empty\n");
    	while (p != NULL)
    	{
    		printf ("Product Number: %d\n", p->element.prod_no);
    		printf ("Product Name  : ");
    		puts (p->element.prod_name);
    		printf ("Price         : %.2f\n",p->element.price);
    		printf ("Stock-on-hand : %.2f\n",p->element.stock_on_hand);
    		getch();
    		p=p->next;
    	}
    }
    
    void locate (int x, list_ptr *L)
    {
    	position p;
    
    	if (*L == NULL)
    		printf ("\n\tList empty\n");
    	else
    	{
    		for (p=*L; p != NULL && p->element.prod_no != x ; p=p->next)
    			;
    		if (p == NULL)
    			printf ("\n\tProduct number doesn't exist\n");
    		else if (p->element.prod_no == x)
    		{
    			printf ("Product name: ");
    			puts (p->element.prod_name);
    			printf ("Price: %.2f\n",p->element.price);
             printf ("Stock-on-hand: %f\n",p->element.stock_on_hand);
    		}
    	}
    }
    
    void makeNull (list_ptr *L)
    {
    	position p;
    
    	if (*L == NULL)
    		printf ("\n\tAlready empty\n");
    	else
    	{
    		while (*L != NULL)
    		{
    			p=*L;
    			(*L)=p->next;
    			free(p);
    		}
    	}
    }
    
    void insert (position x, int p, list_ptr *L)
    {
    	int i;
    	position q,r;
    
    	if (p == 0)
    	{
    		x->next=*L;
    		*L=x;
    	}
    	else
    	{
    		for (i=0, q=*L; q != NULL && i < p; i++, q=q->next)
    			;
    		for (r=*L; r->next != q; r=r->next)
    			;
    		x->next=q;
    		r->next=x;
    	}
    }
    
    void readFile (list_ptr *L)
    {
    	FILE *fp;
    	position p,temp;
    	*L=NULL;
    	if ((fp=fopen("product.dat","rb")) != NULL)
    	{
    		while (!feof(fp))
    		{
    			temp=(position)malloc(sizeof(list));
    			fread (&(temp->element), sizeof(elementtype),1,fp);
    			if (*L == NULL)
    				*L=temp;
    			else
    				p->next=NULL;
    			p=temp;
    		} /* end while */
    
    		p->next=NULL;
    		fclose (fp);
    	} /*end if */
    	else
    		printf ("\n\tUnable to open file\n");
    } /*end read File */

  4. #4
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Eehh. There are more FAQs about scanf, void main(), and non-standard stuff like getch from conio.h and flushall. You'd be well served to look into them as well.

    But I'll just point a couple of places where my linter brings up issues:
    --- Module: test.c (C)
    test.c 55 error [Warning 534] Ignoring return value of function 'flushall(void)' (compare with line 299, file c:\progra~1\borland\bcc55\include\stdio.h)
    test.c 58 error [Warning 613] Possible use of null pointer 'x' in left argument to operator '->' [Reference: file test.c: line 56]
    test.c 60 error [Warning 545] Suspicious use of &
    test.c 60 error [Warning 561] (arg. no. 2) indirect object inconsistent with format
    test.c 60 error [Warning 613] Possible use of null pointer 'x' in left argument to operator '->' [Reference: file test.c: line 56]
    test.c 62 error [Warning 613] Possible use of null pointer 'x' in left argument to operator '->' [Reference: file test.c: line 56]
    test.c 64 error [Warning 613] Possible use of null pointer 'x' in left argument to operator '->' [Reference: file test.c: line 56]
    test.c 65 error [Warning 613] Possible use of null pointer 'x' in left argument to operator '->' [Reference: file test.c: line 56]
    test.c 97 error [Warning 534] Ignoring return value of function 'getch(void)' (compare with line 174, file c:\progra~1\borland\bcc55\include\conio.h)
    test.c 123 error [Warning 613] Possible use of null pointer 'p' in left argument to operator '->' [Reference: file test.c: line 121]
    test.c 125 error [Warning 613] Possible use of null pointer 'p' in left argument to operator '->' [Reference: file test.c: line 121]
    test.c 126 error [Warning 613] Possible use of null pointer 'p' in left argument to operator '->' [Reference: file test.c: line 121]

    During Specific Walk:
    File test.c line 72: deleteElement(?, [1])
    test.c 123 error [Warning 613] Possible use of null pointer 'p' in left argument to operator '->' [Reference: file test.c: line 121]

    During Specific Walk:
    File test.c line 66: insert([1]? | 0?, ?, [1])
    test.c 216 error [Warning 613] Possible use of null pointer 'x' in left argument to operator '->' [Reference: file test.c: lines 56, 66]

    During Specific Walk:
    File test.c line 94: readFile([1])
    test.c 240 error [Warning 613] Possible use of null pointer 'temp' in left argument to operator '->' [Reference: file test.c: line 239]
    And again, I don't care to write "product.dat" and I don't know if anyone else wants to either. Unless anyone volunteers, you may want to post your own.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > typedef list *position;
    > typedef list *list_ptr;
    Typedef'ing pointers is not something I usually do (except for hairy function pointers).
    All it does is save you from typing just ONE extra * elsewhere, but it causes you to have to look up how many real levels of indirection there are rather than having it right in front of you.

    > while (!feof(fp))
    Read the FAQ on why this is bad.

    > temp=(position)malloc(sizeof(list));
    Casting malloc is also poor form in C - also in the FAQ

    > else
    > p->next=NULL;
    You mean p->next = temp surely
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    and Nothing Else Matters
    Join Date
    Jul 2006
    Location
    Philippines
    Posts
    117
    i did write a product.dat here, i wrote 3 records.. the product.dat is 180bytes in size. so far, writeList seems to be on track..

    jeeze, im sorry for all the "errors" im my programming style. as i've said, that's the way i did things becoz that wuz how i was taught. im only learning the "proper" ways right now, so please bear with me...

    so, instead of using what my teacher used (the !feof(fp)), what alternatives could u guys suggest?? thanks! we're having our midterms next week so i gotta get all of this into my system in 3days.. =(

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Code:
    elementtype element;
    while ( fread ( &element, sizeof element, 1, fp ) == 1 ) {
      list *temp = malloc ( sizeof *temp );
      temp->element = element;  // copy the file record into the list node just allocated 
      // now append it to your list
    }
    feof() is a state, not a prediction.
    That is, for a zero length file, feof() will return false until you actually try and read something.

    You have to check the return results of actual file reading functions (fgets, fgetc, fread) to determine whether your input was a success or not.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  8. #8
    Registered User
    Join Date
    Jan 2006
    Location
    Berkeley, Ca
    Posts
    195

    Creating self- and mutually-referential types

    Here is some more comments on your code.

    Code:
    typedef struct prod_record {
            int prod_no;
            char prod_name[50];
            float price, stock_on_hand;
    }elementtype;
    
    typedef struct linked_list {
            elementtype element;
            struct linked_list *next;
    }list;
    Using typedef is in general a bad idea. For the complete technical dissertation, please read the following section titled "Creating self- and mutually-referential types".

    http://web.torek.net/torek/c/types2.html

    Pssstt... the author is used to work at Lawrence Berkeley National Lab and a former NetBSD engineer.

    Also, you should probably free() after using malloc().

  9. #9
    Registered User
    Join Date
    Jan 2006
    Location
    Berkeley, Ca
    Posts
    195
    And for some reason, the edit post thingy option doesn't appear to be working on my account -(.

  10. #10
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    You can't edit your posts after a certain amount of time.

    If you think you've found a problem you can post it in the General Discussions thread about the board upgrade: http://cboard.cprogramming.com/showthread.php?t=81023
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  11. #11
    and Nothing Else Matters
    Join Date
    Jul 2006
    Location
    Philippines
    Posts
    117
    @Salem
    thanks for the hint... =D i tried checking for NULL on my fread().. will it work too???

  12. #12
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    No - read the manual page on fread() to find out what it returns.
    NULL isn't one of the valid return results.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Need help sorting a linked list. Beginner
    By scarlet00014 in forum C Programming
    Replies: 1
    Last Post: 09-27-2008, 06:16 PM
  2. singly linked circular list
    By DarkDot in forum C++ Programming
    Replies: 0
    Last Post: 04-24-2007, 08:55 PM
  3. Replies: 6
    Last Post: 03-02-2005, 02:45 AM
  4. Linked list with two class types within template.
    By SilasP in forum C++ Programming
    Replies: 3
    Last Post: 02-09-2002, 06:13 AM
  5. singly linked list
    By clarinetster in forum C Programming
    Replies: 2
    Last Post: 08-26-2001, 10:21 PM