Linked lists

M

mark.martinez2

I'm having some trouble with a linked list of strings. After I insert
a number of items, I call a print function and every node in the
linked list has the value from the last item I entered into the linked
list. Any ideas? Code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct listNode { /* self-referential structure */
char *data;
int wordLength;
struct listNode *nextPtr;
};

typedef struct listNode LISTNODE;
typedef LISTNODE *LISTNODEPTR;

void insert(LISTNODEPTR *, char *, int);
void printList(LISTNODEPTR);
int isChar(char);
void resetString(void);
char word[50];

main()
{

FILE *fptr;
LISTNODEPTR startPtr = NULL;
int maxLine = 0;
char file_name[20];
int count = 0;
char c;
char d;


printf("Type in the name of the file containing the text: \n");
scanf("%s",file_name);
fptr=fopen(file_name,"r");

int numChar; /* number of characters per line */

//printf("How many characters per line?: ");
//scanf("%d", &maxLine);

c = fgetc(fptr);
int tempCount = 0;

while ((d = fgetc(fptr)) != EOF) {

/* if two new lines in a row */
if ((c == '\n') && (d == '\n')) {
}

/* if not two non-characters in a row */
else if ((isChar(c) == 0) && (isChar(d) == 0)) {
c = d;

printf("%s\n",word);
}
/* if c and d are both characters */
else if ((isChar(c) == 1) && (isChar(d) == 1)) {
word[count] = c;
c = d;
count++;

printf("%s\n",word);
}

/* if c is character and d is space, return, tab, or new line */
else if ((isChar(c) == 1) && (isChar(d) == 0)) {
word[count] = c;

insert(&startPtr, word, count);

c = d;
count = 0;
printf("word: %s\n",word);
resetString();
}

/* if d is start of new word */
else if ((isChar(d) == 1) && (isChar(c) == 0)) {
c = d;

printf("%s\n",word);
}
}

fclose(fptr);
printList(startPtr);
}

void resetString(void) {

int i = 0;
for (i = 0;i < 50;i++) {
word = '\0';
}


}

int isChar(char c) {
if ((c >= 33) && (c <= 126)) {
return 1;
}
return 0;
}

/* insert into list */
void insert(LISTNODEPTR *sPtr, char *value, int length)
{
LISTNODEPTR newPtr, previousPtr, currentPtr;

newPtr = malloc(sizeof(LISTNODE));

if (newPtr != NULL) { /* is space available */
newPtr->data = value;
newPtr->wordLength = length;
newPtr->nextPtr = NULL;

previousPtr = NULL;
currentPtr = *sPtr;

while (currentPtr != NULL && value > currentPtr->data) {
previousPtr = currentPtr; /* walk to ... */
currentPtr = currentPtr->nextPtr; /* ... next node */
}

if (previousPtr == NULL) {
newPtr->nextPtr = *sPtr;
*sPtr = newPtr;
}
else {
previousPtr->nextPtr = newPtr;
newPtr->nextPtr = currentPtr;
}
}
else
printf("%s not inserted. No memory available.\n", value);
}

/* Print the list */
void printList(LISTNODEPTR currentPtr)
{
if (currentPtr == NULL)
printf("List is empty.\n\n");
else {
printf("The list is:\n");

while (currentPtr != NULL) {
printf("%s --> ", currentPtr->data);
currentPtr = currentPtr->nextPtr;
}
printf("NULL\n\n");
}
}
 
J

Jack Klein

I'm having some trouble with a linked list of strings. After I insert
a number of items, I call a print function and every node in the
linked list has the value from the last item I entered into the linked
list. Any ideas? Code:

[snip]

It's a FAQ (a Frequently Asked Question), in particular:

"7.4 I'm reading lines from a file into an array, with this code:
char linebuf[80];
char *lines[100];
int i;

for(i = 0; i < 100; i++) {
char *p = fgets(linebuf, 80, fp);
if(p == NULL) break;
lines = p;
}
Why do all the lines end up containing copies of the last line?"

This situation exactly matches your problem, and of course the answer
in the FAQ will help you fix it.

Always check a group's FAQ before you post, your question might
already be answered there.

There's a link to the FAQ for comp.lang.c in my signature, below.
While you're there, look at all of it. There is a lot of excellent
advice for new, and even not-so-new, C programmers.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
 
M

mark.martinez2

I looked at 7.4 (and 20.2 it references), but I still don't understand
how to apply it to my program. Do I need to allocate memory for each
character since I'm using fgetc? Would I allocate memory in the size
of word[count] right before I call the insert function? Wrapping my
head around all the pointers and memory allocation in this program is
extremely difficult.
 
D

Dann Corbit

I looked at 7.4 (and 20.2 it references), but I still don't understand
how to apply it to my program. Do I need to allocate memory for each
character since I'm using fgetc? Would I allocate memory in the size
of word[count] right before I call the insert function? Wrapping my
head around all the pointers and memory allocation in this program is
extremely difficult.

Here is what you are doing:
1. reading a string of characters into word
2. Giving the address of word to your list element.
3. Read a new string of characters into word
4. Giving the address of word to your list element.
etc.
So every time you copy a new word into the string word, it writes overtop of
the old string.

Here is what you should be doing:
1. Read a string of characters into word
2. Make a copy of the characters like this:
char *copy = malloc(strlen(word)+1);
if (copy) strcpy(copy, word);
point at the duplicate string.

etc.
 
M

mark.martinez2

Ah man I just noticed my reply didn't submit.

I looked at 7.4 and the other FAQ it referenced, and I still cannot
figure out how to fix this in my program. I understand the basic
concept of what I'm doing wrong, but somewhere among all the pointers
and memory allocations, I get completely lost.
 
M

mark.martinez2

Jack,

Sorry to email you directly but I've been trying to post a reply to my
post in comp.lang.c and it won't show up.

After looking at the FAQs, I understand the basic concept of what I'm
doing wrong, but somewhere amidst all the memory allocations and
pointers, I'm lost on how to address this issue in my program. Memory
allocation is very new to me and something I have not covered in
depth, so perhaps that is my weakness.

Mark
 
U

user923005

Jack,

Sorry to email you directly but I've been trying to post a reply to my
post in comp.lang.c and it won't show up.

After looking at the FAQs, I understand the basic concept of what I'm
doing wrong, but somewhere amidst all the memory allocations and
pointers, I'm lost on how to address this issue in my program. Memory
allocation is very new to me and something I have not covered in
depth, so perhaps that is my weakness.

/* insert into list */
void insert(LISTNODEPTR * sPtr, char *value, size_t length)
{
LISTNODEPTR newPtr,
previousPtr,
currentPtr;
newPtr = malloc(sizeof(LISTNODE));
if (newPtr != NULL) { /* is space available */
/
*************************************************************************/
newPtr->data = malloc(length); /* should be strlen(word)+1 */
if (newPtr->data == NULL) {
printf("Out of memory in %s at line %s\n", __FILE__,
__LINE__);
exit(EXIT_FAILURE);
}
strcpy(newPtr->data, value);
/
*************************************************************************/
newPtr->wordLength = length;
newPtr->nextPtr = NULL;
previousPtr = NULL;
currentPtr = *sPtr;
while (currentPtr != NULL && value > currentPtr->data) {
previousPtr = currentPtr; /* walk to ... */
currentPtr = currentPtr->nextPtr; /* ... next node */
}
if (previousPtr == NULL) {
newPtr->nextPtr = *sPtr;
*sPtr = newPtr;
} else {
previousPtr->nextPtr = newPtr;
newPtr->nextPtr = currentPtr;
}
} else {
printf("%s not inserted. No memory available.\n", value);
exit(EXIT_FAILURE);
}
}
 
C

CBFalconer

I'm having some trouble with a linked list of strings. After I
insert a number of items, I call a print function and every node
in the linked list has the value from the last item I entered
into the linked list. Any ideas? Code:
.... snip ...

struct listNode { /* self-referential structure */
char *data;
int wordLength;
struct listNode *nextPtr;
};

I suggest you keep your node simple. I see no need for wordLength.

Then you should acquire the string (from whereever), create a new
struct listNode, set nextPtr to the base node, and then set the
base node to point to that new struct listNode. This will form the
list in reverse order, i.e. the last entry will be first in the
list.

Thus the entry mechanism will be a routine:

struct listNode *putinlist(struct listNode *list, char *line);

and you will possibly have a string reversal routine:

struct listNode *revlist(struct listNode *list);

With this collection it will be trivial to form the list, print it,
destroy it, sort it, etc.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,810
Latest member
Kassie0918

Latest Threads

Top