2

I am having some problems creating a linked list and also some helper functions that I am trying to make. My code is as follows:

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include "getNextWord.h"

#define MAX_WORD_SIZE 256

typedef struct{
int counter;
char* key;
struct node* next;
} node;

node* createNode(char* words){
    node* head;
    if(!(head=malloc(sizeof(node)))) return NULL;
    head->key=words;
    head->next=NULL;
    return head;
}

node* addToList(node* head, char* words){
    node* newNode;
    newNode=createNode(words);
    newNode->next = head;
    return newNode;
}

int find(node* head){
    if (head->next != NULL){
        node* next = head->next;

        while(head != NULL){
            if (strcmp(head->key,next->key)==0){
                head->counter++;
                head=head->next;
                return 1;
                }
            else{
                head=head->next;
                }
            }
    }
return 0;
}

void printList(node* head){
    node* pointer = head;
    while (pointer != NULL){
        printf("%s",pointer->key);
        pointer=pointer->next;
        }
    printf("\n");
}

int main(int argc, char* argv[]){

    if(argc<2){
        fprintf(stderr, "Not enough arguments given\n");
        }

    for(int i=1; i< argc; i++){
        FILE* fd=fopen(argv[i], "r");
        if(fd != NULL){
            char* words;
            node* head = NULL;
            while((words=getNextWord(fd)) != NULL){
                find(head);
                if (find(head) == 0){
                    createNode(words);
                    }
                printList(head);


                fprintf(stdout,"%s\n",words);
                }
            }

        else(printf("No such file exists"));
        fclose(fd);
        }
return 0;
}

I looked around on the Internet and it would seem I am following what most people are doing in regards to the linked list. I wasn't getting any errors before, just a bunch of "warning: assignment from incompatible pointer type" in the following functions:

addtolist (the line before the return)
find (before return one and the else line)
printlist (the last line in the while loop)

I know it's not that great of code, I'm not the best programmer, but just trying to learn. Also, my getnextword does work, but if it's needed for something I can post that too.

4 Answers 4

5

Your are mixing up two different "namespaces" the "tag" namespace for struct and alike and the identifier namespace for typedef. The easiest to get along with this is to forward declare the types you are going to use:

typedef struct node node;

Then afterwards you can use node or struct node interchangeably. Even inside

struct node {
  // something
  node * next;
};
Sign up to request clarification or add additional context in comments.

2 Comments

If your saying that I shouldn't name things node* node then that makes sense. I was naming them node* somethingelse (obviously not exactly that) and that is when I wasn't getting any errors but was still getting the warnings, which ended in a segmentation fault in my first find statement, which now makes sense since ->next is NULL at that point and it should crash. I can change it back over and edit my first post to what I had before.
Also, a node* and a struct node* are two different things, unless you make them not two different things as described here.
0
typedef struct tag_node {
    int counter;
    char* key;
    struct tag_node* next;
} node;

for starters.

As a side-note, I can't imagine how you free() words within main (careful, it might leak).

edit - I accidentally some styles

1 Comment

This one gets rid of the warnings that I was getting but not the errors. I thought that you didn't need to have a name after struct if using typdef, just at the end. But then again, I am very new to all this and could easily be wrong.
0

Try this:

struct node {
  int counter;
  char* key;
  struct node* next;
};

You may need to replace node with struct node in other places in the code.

3 Comments

Wouldn't I then have to add "struct" in front of "node" every time? I thought that is what typedef was used for, so you didn't have to write struct every time you wanted some sort of reference to what you were making.
@Defc0n - Yes, that is true as I said in my last line. It is a matter of style, some programmers prefer the typedef other feel it makes the code harder to read. It is not a macro so it behaves a little differently than a simply a text replacement.
yeah, I seemed to have missed that line the first time I read it. In my defense I had only slept about 3 hours. I got rid of the errors I was having, now I just need to deal with the warnings.
0

multiple issues:

int find(node* node){
    node* next = node->next;  // what if next is NULL ?
    while(node != NULL){
        if (strcmp(node->key,next->key)==0){ // if next is NULL this will crash
            node->counter++;
            return 1;
            node=node->next;   // never reached since return 1 above.
            }
        else{
            node=node->next;
            }
    }
return 0;
}

....

probably good to rename createlist to createnode since that seems to be the function.

node* createList(char* words){
    node* node;
    if(!(node=malloc(sizeof(node)))) return NULL;
    node->key=words;
    node->next=NULL;
    return node;
}

the string that comes in 'words' is never stored, you need to create a copy of the words and store it e.g.:

node->key = strdup(words);

1 Comment

My getnextword function (that I didn't include) does do a strdup of the words already. Is this one still necessary or would that be allocating memory for the same thing twice? And yes, stupid mistake with returning 1 where I did, not thinking there. Also, for the first error there, I could just add a simple if (node->next != NULL) then do that statement correct?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.