Click to See Complete Forum and Search --> : create doubly linked list with .txt file contents read each line as string


jaeezzy
May 1st, 2009, 09:54 PM
Hi, I'm new to C programming and its been two days trying to figure out how I can create a doubly linked list from a .txt file in the same directory. What I'm trying to do is, read the data in the file and while reading, I want to populate DLList. I'm reading line by line in a file and I'm trying to insert each line in nodes but couldn't achieve it. Here's how I've tried please help me where i'm doing wrong. thank you.
==========================================================================================
#include <stdio.h>
#include <stdlib.h>

#define MAX_INPUT 10

struct dllist
{
char *string;
struct dllist *nextPtr;
struct dllist *prevPtr;
};

typedef struct dllist DLList;
typedef DLList *DLListPtr;

void dllInit(DLListPtr*);
void printList(DLListPtr);
DLListPtr makeNode(char c[BUFSIZ]);

int main(int argc, char** argv)
{
DLListPtr head = NULL;
char input[MAX_INPUT];
while (input[0] != 'q')
{
printf(">>");
fgets(input, MAX_INPUT, stdin);

switch (input[0])
{
case 'a':
dllInit(&head);
break;

case 'p':
printList(head);
break;

case 'q':
printf("BYE");
exit(0);
break;

default:
printf("Invalid input.\n");
break;
}
}

return 0;
}

DLListPtr makeNode(char value[BUFSIZ])
{
DLListPtr lnode = malloc(sizeof(DLList));
if (lnode != NULL)
lnode->string = value;
return lnode;
}

void dllInit(DLListPtr *startPtr)
{
DLListPtr curPtr;
char data[BUFSIZ];
FILE *filePtr;
if ((filePtr = fopen("text.txt", "r")) == NULL)
{
printf("READ ERROR!!");
exit(1);
}
while (fgets(data, BUFSIZ, filePtr) != NULL)
{
if (*startPtr == NULL)
{
*startPtr = makeNode(data);
printf("%s\n", (*startPtr)->string);
(*startPtr)->nextPtr = NULL;
(*startPtr)->prevPtr = NULL;
}
else
{
curPtr = *startPtr;
for (;curPtr->nextPtr;)
curPtr=curPtr->nextPtr;
DLListPtr newPtr = makeNode(data);
newPtr->prevPtr = curPtr;
newPtr->nextPtr = curPtr->nextPtr;
curPtr->nextPtr = newPtr;
printf("%s\n", newPtr->string);
}
}
}

void printList(DLListPtr nodePtr)
{
if (nodePtr == NULL)
printf("The List is empty.\n");
while (nodePtr != NULL)
{
printf("Element: %s", nodePtr->string);
nodePtr = nodePtr->nextPtr;
}
}

==========================================================================================
printList(...) just prints the last line of the file and the file is simply contains:

aaa aaa aaaaaaaa a
bb bb bbbbb b
cccccc cccccccccc cc ccccc

and each line is separated by "\n" and even the last line.

SlickHawk
May 2nd, 2009, 02:00 PM
lnode->string = value;

That's a big problem. That assignment is simply copying the pointer to the string, which, as we can find by travelling up the stack, is just data's value. That array is getting overwritten every iteration of the loop.

The easy way to fix this is instead of your nodes having character pointers, they have arrays instead. This'll work because you have a predefined BUFSIZ. The disadvantage to this is that now your nodes will be big (very big if BUFSIZ is large). The more correct way would be to dynamically allocate the string. Yes, this means you'll be issuing two calls to malloc, one for the node, and one for the string in the node. You'll want to use strlen (plus 1) to determine how many bytes to allocate, and strcpy to deep copy the characters into your new buffer.

jaeezzy
May 3rd, 2009, 11:43 PM
That's a big problem. That assignment is simply copying the pointer to the string, which, as we can find by travelling up the stack, is just data's value. That array is getting overwritten every iteration of the loop.

The easy way to fix this is instead of your nodes having character pointers, they have arrays instead. This'll work because you have a predefined BUFSIZ. The disadvantage to this is that now your nodes will be big (very big if BUFSIZ is large). The more correct way would be to dynamically allocate the string. Yes, this means you'll be issuing two calls to malloc, one for the node, and one for the string in the node. You'll want to use strlen (plus 1) to determine how many bytes to allocate, and strcpy to deep copy the characters into your new buffer.

Thanks for the reply SlickHawk, I got it solved.