0

As my current function stands I can only read the first set of data from a file. I am sure that it is because of the !feof not functioning the way I want it to but it might also be caused by a bad print list function but I am not to sure. I am pretty much brand new to using dynamic memory so bear with me.

Load from File

void load(FILE *file, Node *head)
{
    char tempArtist[30] = {'\0'}, tempAlbum[30] = {'\0'}, tempTitle[30] = {'\0'}, tempGenre[30] = {'\0'}, tempSpace = '\0';
    SongLength *tempLength = NULL;
    char tempPlay[100] = {'\0'}, tempRating[6] = {'\0'}, tempMins[3] = {'\0'}, tempSecs[3] = {'\0'};

    tempLength = (SongLength *)malloc(sizeof(SongLength));

    while (!feof(file))
    {
        while (head->pNext == NULL) // Here is where I need to shift to the next node
        {
            fscanf(file, "%s", &tempArtist);
            fscanf(file, "%c", &tempSpace);

            strcpy(tempLength->mins, tempMins);
            strcpy(tempLength->secs, tempSecs);
            strcpy(head->data->artist, tempArtist);
            strcpy(head->data->length->mins, tempLength->mins);
            strcpy(head->data->length->secs, tempLength->secs);

            insertNode(head, head->data);
        }
    }
    free(tempLength);
}

Insert to linked list

void insertNode(Node *head, Record *data)
{
    while(head->pNext == NULL)
    {
        head=head->pNext;
    }

    head->pNext=(Node*)malloc(sizeof(Node));
    head->pNext->data = (Record*)malloc(sizeof(Record));
    head->pNext->data->length=(SongLength*)malloc(sizeof(SongLength));

    (head->pNext)->pPrev=head;
    head=head->pNext;
    head->data=data;
    head->pNext=NULL;

}

Print all of the data in the list(hopefully)

void display (Node *head)
{

    while (head->pNext != NULL)
    {
        printf ("Artist: %s\n", head->data->artist);
        printf ("Length(mm:ss) %s:%s\n", head->data->length->mins,head->data->length->secs);

        head=head->pNext;
    }
    putchar ('\n');
}

I have removed all but one of the fscanf()'s and printf()'s to cut down the code.

Structs

typedef struct songlength
{
    char mins[3];
    char secs[3];
}SongLength;

typedef struct record
{
    char artist[30];
    struct songlength *length;      
}Record;

typedef struct node
{
    struct node *pPrev;
    struct record *data;
    struct node *pNext;
}Node;
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 1
    http://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong – Gopi Feb 09 '15 at 05:38
  • @Gopi If I don't use feof, then what can I use instead to tell if I am at the end of a file? – user3482104 Feb 09 '15 at 05:44
  • regarding the calls to malloc() 1) in C, do not cast the returned value from malloc (and family) 2) always check the returned value to assure the operation was successful (!= NULL) – user3629249 Feb 09 '15 at 05:48
  • in the insertNode function, always check that '*head' is not NULL and handle the special case when it is NULL and the parameter 'node *head' should probably be ' node **head' so that the head pointer can be changed when inserting the very first node – user3629249 Feb 09 '15 at 05:51
  • @user3482104 The question must be well framed so that anyone reading it comes to know what the problem is .. if you paste some API's and ask what is wrong it might be hard to answer it.. Use `while(fscanf("%s %c",&tempArtist,&tempSpace) == 2)` to read till end of file – Gopi Feb 09 '15 at 05:52
  • this line: 'head->data=data;' in the insertNode function overlays the data point that was malloc'd just a few lines above. this results in a large memory leak. suggest using a debugger, suggest drawing out the operations in a nice pictorial, so you can see what is actually happening. – user3629249 Feb 09 '15 at 05:59
  • @Gopi I know that would work, but I want to write this so that I don't have to know the number of items to read from the file. – user3482104 Feb 09 '15 at 06:01
  • @user3629249 If I make head a double pointer, then how would I malloc for it? Also how would I gain access to pNext,pPrev,and data within **head? – user3482104 Feb 09 '15 at 06:08
  • You are trying to solve two problems at once: reading a file and appending data to a list. Tackle them one at a time. – Beta Feb 09 '15 at 06:22
  • You only need to use `feof()` after you detected a problem (EOF or error) with a regular I/O function and need to tell the difference between EOF and an error. Read the x-ref'd [question (and its answers)](http://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong) for more information about why `while (!feof(file))` is wrong and what to do about it. – Jonathan Leffler Feb 09 '15 at 07:04

1 Answers1

1

the function call insertNode(head,head->data); looks strange. The second argument have to be data not from the head, otherwise data in head is rewritten for any new record.

So allocate memory for Record inside load function and do not use head->data.

VolAnd
  • 6,367
  • 3
  • 25
  • 43
  • So just something like this? tempRecord=(Record*)malloc(sizeof(Record)); and then pass in tempRecord to instertNode? – user3482104 Feb 09 '15 at 06:31
  • Yes. I mean this. But may be other changes will be needed in the code – VolAnd Feb 09 '15 at 06:34
  • So, that may or may not have worked, but I need to shift to the next node so that I can store the next set of data. Ill mark the line in the main body with a comment. – user3482104 Feb 09 '15 at 06:59
  • For shift to next item in the list (to reach the last element) other pointer can be used. I mean, you should not change `head`, but use local variable assigned from `head`, e.g. `Node * current = head;` – VolAnd Feb 09 '15 at 08:28
  • I just read your code (not debug or run), so it is hard to say what else need improvement or rewriting. – VolAnd Feb 09 '15 at 09:40