Thread: Inexplicable Linked List Problem

  1. #1
    Registered User
    Join Date
    Jun 2004
    Posts
    93

    Inexplicable Linked List Problem

    Well it's inexplicable at least to me.

    This program reads from a file, which I have attached, and then prints out information.

    For some strange, strange reason, the linked list prints out the name just fine when inside a function, but doesn't print it fine when outside of a function.

    I checked the addresses, and they both point to the same place. WHAT THE HELL is going on?

    Thanks for any help.

    Code:
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define MAX_NAME 30
    
    void InputFile (char* input_file);
    void OpenFile (char* input_file);
    
    
    struct student
    {
       char *name;
       int exam1;
       int exam2;
       int exam3;
       int exam4;
       int exam5;
       char grade;
       int average;
       struct student *next;
    };
    
    typedef struct student student;
    
    student* AddNode (char *name, int exam1, int exam2, int exam3, int exam4, int exam5, student *head);
    student* StudentInfo(FILE *input_stream, int students_registered, int exam_number, student *head);
    int main ()
    
    {
    
        char input_file[BUFSIZ];
    
        InputFile(input_file);
    
        OpenFile(input_file);
    
        getchar();
        getchar();
    
        return 0;
    }
    
    void InputFile (char* input_file)
    {
    
        printf("Enter the name of the file containing the grades.\n");
        scanf("%s", input_file);   //Retrieving filename from user
    
        return;
    }
    
    void OpenFile (char* input_file) //Collect necessary information from file
    {
         FILE *input_stream;
    
         char* file = input_file;
    
         int students_registered;
         int exam_number;
    
         student *head = NULL;           //Creation of Head for Sorted Linked List
         head = malloc(sizeof(student));
    
         if ( (fopen(input_file, "r")) == NULL )
         {
            printf("Could not open file.\n\n");
            return;
         }
    
         else
            input_stream = fopen(input_file, "r");
    
            //Figuring out how many students are registered and number of exams
            fscanf(input_stream, "%d %d", &students_registered, &exam_number);
    
            //Calling StudentInfo function to figure out rest of student information
            head = StudentInfo(input_stream, students_registered, exam_number, head);
            //puts(head->next);
    
            printf("<%s %d>\n",head->name, head->name);
            printf("%s %d %d %d\n", head->name, head->exam1, head->exam2, head->exam3); //Inside Main Function, where it messes up
    
    
            fclose(input_stream);
    
            return;
    }
    
    student* AddNode (char name[], int exam1, int exam2, int exam3, int exam4, int exam5, student *head)
    {
         int i;
    
         student *node;
         node = malloc(sizeof(student));
    
         node->name  = name;
         node->exam1 = exam1;
         node->exam2 = exam2;
         node->exam3 = exam3;
         node->exam4 = exam4;
         node->exam5 = exam5;
         //node->grade = grade;  //Dont forget to do function
         //node->average = average;
    
         node->next  = head;
         head = node;
    
         return head;
    }
    
    student* StudentInfo(FILE *input_stream, int students_registered, int exam_number, student *head)
    {
         int i, j;
         char last_name[MAX_NAME];
         char first_name[MAX_NAME];
         char *name;
         int exam[5];
         char *p;
    
         for(i = 0; i < students_registered; i++)
         {
               fscanf(input_stream, "%s", last_name);
               fscanf(input_stream, "%s", first_name);
    
               //Formatting name
               strcpy(last_name + strlen(last_name), " ");
               name = strcat(last_name, first_name);
    
               for(j = 0; j < exam_number; j++)
               {
                     fscanf(input_stream, "%d", &exam[j]);
               }
    
               switch (j)
               {
                      case 1: head = AddNode (name, exam[0], -1, -1, -1, -1, head);
                              break;
    
                      case 2: head = AddNode (name, exam[0], exam[1], -1, -1, -1, head);
                              break;
    
                      case 3: head = AddNode (name, exam[0], exam[1], exam[2], -1, -1, head);
                              break;
    
                      case 4: head = AddNode (name, exam[0], exam[1], exam[2], exam[3], -1, head);
                              break;
    
                      case 5: head = AddNode (name, exam[0], exam[1], exam[2], exam[3], exam[4], head);
                              break;
                 }//End of Switch
               }//End of for loop
               printf("<%s %d>\n",head->name, head->name);
               printf("%s %d %d %d\n", head->name, head->exam1, head->exam2, head->exam3); //Outside of main function
                //printf("%d", &*head.name);
          return head;
    } //End of StudentInfo Function
    By the way, I know I haven't freed the stuff yet and I will switch most of my input functions to fgets once I get it working. But fgets right now unnecessarily complicates things.
    Last edited by Beast(); 02-05-2005 at 09:05 PM.

  2. #2
    Handy Andy andyhunter's Avatar
    Join Date
    Dec 2004
    Posts
    540
    For some strange, strange reason, the linked list prints out the name just fine when inside a function, but doesn't print it fine when outside of a function.
    I'm sorry, what do you mean by this? Outside of what function? Do you mean when you try to print it out from main?
    i don't think most standard compilers support programmers with more than 4 red boxes - Misplaced

    It is my sacred duity to stand in the path of the flood of ignorance and blatant stupidity... - quzah

    Such pointless tricks ceased to be interesting or useful when we came down from the trees and started using higher level languages. - Salem

  3. #3
    Registered User
    Join Date
    Jun 2004
    Posts
    93
    I'm sorry man, that was rather vague.

    I fixed it so it was understandable.

  4. #4
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    You have multiple issues here.

    1) Why are you mallocing a node here?
    Code:
    void OpenFile (char* input_file) //Collect necessary information from file
    {
         FILE *input_stream;
    
         char* file = input_file;
    
         int students_registered;
         int exam_number;
    
         student *head = NULL;           //Creation of Head for Sorted Linked List
         head = malloc(sizeof(student));
    2) Why does your "OpenFile" function try to do everything? Shouldn't it just "open the file"? Poor design.

    3) This is just wrong.
    Code:
    if ( (fopen(input_file, "r")) == NULL )
         {
            printf("Could not open file.\n\n");
            return;
         }
    
         else
            input_stream = fopen(input_file, "r");
    Why are you doing it that way? You're opening a file that's already open. Boooooo.

    Code:
    if( (input_stream = fopen( input_file, "r" )) == NULL
    {
        printf("Could not open file.\n\n");
        return;
    }
    /* if you're here, it's open and set up correctly for you */
    4) If you're trying to have a dummy node be the end of your list, you're doing a poor job of it, because you never initialized any of its values. If you're not trying to do that, you're still doing a poor job, because you shouldn't have allocated that node previously, since you don't actually do anything with it:
    Code:
    //Calling StudentInfo function to figure out rest of student information
    head = StudentInfo(input_stream, students_registered, exam_number, head);
    5) Here's your real problem:
    Code:
    for(j = 0; j < exam_number; j++)
               {
                     fscanf(input_stream, "%d", &exam[j]);
               }
    
               switch (j)
               {
                      case 1: head = AddNode (name, exam[0], -1, -1, -1, -1, head);
                              break;
    
                      case 2: head = AddNode (name, exam[0], exam[1], -1, -1, -1, head);
                              break;
    
                      case 3: head = AddNode (name, exam[0], exam[1], exam[2], -1, -1, head);
                              break;
    
                      case 4: head = AddNode (name, exam[0], exam[1], exam[2], exam[3], -1, head);
                              break;
    
                      case 5: head = AddNode (name, exam[0], exam[1], exam[2], exam[3], exam[4], head);
                              break;
                 }//End of Switch
               }//End of for loop
    Aside from horrible indentation, that is. What exactly is the value of j when you call that switch. Also, that switch is outside your for loop, so it's only getting called one time. Is that what you want? I doubt it.

    At any rate, I'd be willing to bet 'AddNode' never gets called. As such, you just end up with your unneeded, uninitialized, unuseful, origional node when this function ends. Which is why it doesn't print anything correctly.

    Quzah.
    Hope is the first step on the road to disappointment.

  5. #5
    Registered User
    Join Date
    Jun 2004
    Posts
    93
    Thanks for the response.

    I agree, the program has a poor design concept to it at times. I will fix this later.

    However when I go to fix the fopen() problem, it just crashes. I have not yet figured out why.

    As to the node, I will look into that as well.

    However the last for loop is a nested for loop, the switch statement does get called every time around. The value of j is exactly what I want it to be.

    Thanks for tearing my program apart; all criticism is most welcome. I still have no idea why it messes up when I try to print though.

  6. #6
    Handy Andy andyhunter's Avatar
    Join Date
    Dec 2004
    Posts
    540
    Alright so basically in your struct you had name declared as a pointer to a char. This does not work as in during your assignment for your new node you set the node's char* name equal to the char* name in the function, aka you were just setting pointers equal to eachother. Unfortunately when your studentInfo function ended the variable name lost scope and thus the pointer in your structure points to free memory which is undefined as to what will happen. to fix this change you declaration of your structure to :
    Code:
    struct student
    {
       char name[2*MAX_NAME + 1];
       int exam1;
       int exam2;
       int exam3;
       int exam4;
       int exam5;
       char grade;
       int average;
       struct student *next;
    };
    And in your add node function do this:
    Code:
         strcpy(node->name,name);
         node->exam1 = exam1;
         node->exam2 = exam2;
         node->exam3 = exam3;
         node->exam4 = exam4;
         node->exam5 = exam5;
    That should solve your problem for now.
    i don't think most standard compilers support programmers with more than 4 red boxes - Misplaced

    It is my sacred duity to stand in the path of the flood of ignorance and blatant stupidity... - quzah

    Such pointless tricks ceased to be interesting or useful when we came down from the trees and started using higher level languages. - Salem

  7. #7
    Registered User
    Join Date
    Jun 2004
    Posts
    93
    Ah I understand now.

    Thank you so much andyhunter, I really appreciate it.

    It's much clearer now.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 6
    Last Post: 03-02-2005, 02:45 AM
  2. Linked List
    By jpipitone in forum C Programming
    Replies: 4
    Last Post: 03-30-2003, 09:27 PM
  3. Linked list with two class types within template.
    By SilasP in forum C++ Programming
    Replies: 3
    Last Post: 02-09-2002, 06:13 AM
  4. singly linked list
    By clarinetster in forum C Programming
    Replies: 2
    Last Post: 08-26-2001, 10:21 PM