Thread: Seeking some help in a Linked Lists program

  1. #1
    Registered User
    Join Date
    Apr 2010
    Posts
    3

    Seeking some help in a Linked Lists program

    Hey everybody,

    I'm working on a class project on linked lists and files in C. I can't find the reason why I get a runtime error in two functions.

    The requirements are : For the first function, it has to read in a binary file containing a linked list of CDs and store them in memory. The second one has to read in a text file and store in memory at the beginning of the list for each CD.

    Here is the code: (The cd_t type is a struct that contains many elements)
    Code:
    typedef struct node Node;
    struct node {
    	cd_t CD; 
    	Node *next;
    	};
    	
    typedef struct {
         Node *head;    // pointer to the head of the list
         int num_CDs;          
    } cd_collection_t;
    
    void ReadCollectionFromBinFile (cd_collection_t *collection) 
    {
    	FILE *bfp;
    	char filename[15], choice='Y';
            Node *node;
            (*collection).head = (Node*) malloc(sizeof(Node));
    	(*collection).head->next = NULL ;
    	node = (*collection).head;
    
    	
    printf("\nEnter the name of the file to be read: ");
    scanf("%s", filename);
    if((*collection).num_CDs!=0) {
    	printf("\nData in memory will be overwritten, OK? (Y or N): ");
    	scanf(" %c", &choice); 
    	}
    else node = (Node*) malloc(sizeof(Node));
    
    if(choice=='Y' || choice=='y') 
    	{
    	while((bfp=fopen(filename, "rb"))==NULL) 
    	  {
    		printf("\nCould not open the file, enter the name again: ");
    		scanf("%s", filename); 
    	  }
    	while(node != NULL) {  
    		fread(node, sizeof(Node), 1, bfp);
    		node->next = (Node*) malloc(sizeof(Node));
    		node = node->next;
    		node->next = (*collection).head;
    		(*collection).head = node; 
    	}
    	printf("\nSuccess: Data has been written to memory.");
    	fclose(bfp);
    	}
    	printf("\nReturning to menu...");	
    }
    
    void ReadCollectionFromTextFile (cd_collection_t *collection){
     FILE *txtfp;
     char filename[20];
     char line[100], choice='Y';
     int  i=0;
     Node *new_node = (Node*) malloc(sizeof(Node));
     
    (*collection).head = (Node*) malloc(sizeof(Node));
     (*collection).head->next = NULL;
     
     (*collection).num_CDs=0;
     
     	if((*collection).num_CDs>0){
        printf("There is data in  memory. Continue will overwrite. OK? Y or N:  ");
        scanf(" %c", choice);
        }
        if(choice == 'Y') {
        	printf("\nEnter the name of the file to be read: ");
    		for(scanf("%s", filename); (txtfp=fopen(filename, "w")) == NULL; scanf("%s", filename))
    			printf("\nFile could not be opened, reenter file name: ");
         	fgets(line,100,txtfp);
            if(feof(txtfp))
            	printf("\nFile is empty.");
            else{
            	while(!feof(txtfp)&&(*collection).num_CDs<CSIZE){
            		printf("\nZOOB");
            		new_node->next = (*collection).head;
    				(*collection).head = new_node;
           			ReadCDFromTextFile (new_node,txtfp);
    				new_node->next = (Node*) malloc(sizeof(Node));    
              		(*collection).num_CDs++;
                 }
            }
          }
    
         fclose(txtfp);
    }
    //***************************************************************************
    void ReadCDFromTextFile ( Node* cd, FILE *txtfp){
        char line[100];
        char delim[]=":";
        char *token;
        int i=0;
        cd->CD.total_time_mins = cd->CD.total_time_secs=0;
     
     	fgets(line,100,txtfp);
      	if(feof(txtfp))
        printf("\nFile has ended.");
        
    	else{
         while(!feof(txtfp) && line[0]!='\n'){
         if(line[0]=='\n') 
    	 fgets(line,100,txtfp);   
         strcpy(cd->CD.album,line);
         printf("\n%s",cd->CD.album);
         fgets(line,100,txtfp);
         strcpy(cd->CD.publisher,line);  
         printf("\n%s",cd->CD.publisher);
         fscanf(txtfp,"%s",cd->CD.identifier);
         printf("\n%s",cd->CD.identifier);
         fscanf(txtfp,"%d",cd->CD.num_tracks);
         fgets(line,100,txtfp);
         fgets(line,100,txtfp);
         cd->CD.CDType=line[0];       
         
     	if(cd->CD.CDType=='s'||cd->CD.CDType=='S'){
         	fgets(line,100,txtfp);
        	strcpy(cd->CD.track_info[0].artist,line);      
         	fgets(line,100,txtfp);
            while(line[0]!='\n'){
         	token = (char*)strtok(line,delim);
               strcpy(cd->CD.track_info[i].track_name,token);
               printf("\n%s",cd->CD.track_info[i].track_name);          
               token = (char*)strtok(NULL,delim);
     	       cd->CD.track_info[i].minutes=atoi(token);
     	       printf("\nMin: %d",cd->CD.track_info[i].minutes);
       		   token = (char*)strtok(NULL,delim); 
       	       cd->CD.track_info[i].seconds=atoi(token);
            	printf("\nSec:%d",cd->CD.track_info[i].seconds);
            	fgets(line,100,txtfp);
            	i++;      
            	if(feof(txtfp))
           		break; 
              }
            }     
         else if(cd->CD.CDType == 'm' || cd->CD.CDType == 'M' ){
         fgets(line,100,txtfp);
         	while(line[0]!='\n'){
          		token=(char*)strtok(line,delim); 
          		strcpy(cd->CD.track_info[i].artist,token);
          		printf("\n%s",cd->CD.track_info[i].artist);
          		token = (char*)strtok(NULL,delim);
          		strcpy(cd->CD.track_info[i].track_name,token);
          		printf("\n%s",cd->CD.track_info[i].track_name);
          		token = (char*)strtok(NULL,delim); 
             	cd->CD.track_info[i].minutes=atoi(token); 
             	printf("\nMin: %d",cd->CD.track_info[i].minutes);
          		token=(char*)strtok(NULL,delim);
             	cd->CD.track_info[i].seconds=atoi(token);
             	printf("\nSec: %d",cd->CD.track_info[i].seconds);          
             	i++;
                if(feof(txtfp))
               	break;
              	fgets(line,100,txtfp);
                } 
          }
          cd->CD.total_time_mins+=cd->CD.track_info[i].minutes;
          cd->CD.total_time_secs+=cd->CD.track_info[i].seconds;
    	  if(cd->CD.total_time_secs>=60) {
    	  cd->CD.total_time_secs-=60;
    	  cd->CD.total_time_mins+=1; 
    	  }
       }
       
      }}

  2. #2
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    So what are the exact errors you get?

  3. #3
    Registered User
    Join Date
    Apr 2010
    Posts
    3
    The program compiles. When I run it and choose to use the readfrombin function from the menu (in the main), I select a bin file that I've created using another function, I get a runtime error.
    Concerning the second function, I get an infinite loop.

  4. #4
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Code:
    while(node != NULL)
    your loop runs till all the memory is allocated trying to read a lot longer than there is data in the file
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  5. #5
    Registered User
    Join Date
    Apr 2010
    Posts
    3
    I changed it to while(node->next != NULL) but it still not working.

  6. #6
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    A few things to consider:

    1)What is the name of the bin file you are reading from? Does the name fit in the 15 char array you have there?

    2)Stop casting malloc, unless you are compiling in C++ or something.

    3)Try using a debugger to step through each line in that function and see where exactly you get the runtime error. That would help a lot in figuring out what is going on, particularly because we don't know the contents of your input file.

  7. #7
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Using feof to control loops is problematic.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  8. #8
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Quote Originally Posted by shinigami01 View Post
    I changed it to while(node->next != NULL) but it still not working.
    And why should it? How this pointer value is related to the size of file you are reading?
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  9. #9
    Registered User
    Join Date
    Aug 2007
    Location
    MD, USA
    Posts
    71
    Why are we guessing? We are not mind readers.
    There are many potential problems possible in what you have posted.

    Why don't you post a complete minimal example using the function that fails.
    By complete I mean ALL components present , ready to compile and run or error.
    That we we can see what you are seeing.
    Practice makes ....well improvement anyhow , hopefully.
    Last edited by HowardL; 04-05-2010 at 11:53 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 09-16-2009, 06:00 AM
  2. Unknown memory leak with linked lists...
    By RaDeuX in forum C Programming
    Replies: 6
    Last Post: 12-07-2008, 04:09 AM
  3. Linked list of linked lists???
    By Qui in forum C++ Programming
    Replies: 6
    Last Post: 03-28-2004, 01:13 PM
  4. Map file formats and linked lists
    By Spitball in forum Game Programming
    Replies: 2
    Last Post: 03-04-2004, 11:32 PM
  5. Replies: 2
    Last Post: 01-18-2003, 01:32 AM