link list printing issue? - c

I try to print a linked list but it didn't print all of the member in the list.can you explain what is the issue in my code? is code line (newhead=newhead->next) moves even the rest of the list is on the another function?
#include <stdio.h>
#include <stdlib.h>
struct test_struct{
int data;
struct test_struct *next;
};
struct test_struct* create();
void add_node();
int main()
{
add_node();
return 0;
}
void add_node()
{
struct test_struct* head = create();
struct test_struct* newhead;
newhead = malloc(sizeof(struct test_struct));
newhead->data=2;
newhead->next=head;
head=newhead;
while(newhead->next != NULL)
{
printf("%d\n",newhead->data);
newhead=newhead->next;
}
}
struct test_struct* create()
{
struct test_struct* head=NULL;
struct test_struct* temp = (struct test_struct*)malloc(sizeof(struct test_struct));
if(NULL==temp)
{
printf("error in memory");
return 0;
}
temp->data=5;
temp->next=head;
head=temp;
return head;
}

Your while loop stops when it is on a node with no next node; it doesn't print the data on that node.
Instead, you want to stop when it is pointing to no node; that is, just after it's "fallen off the end" of your list:
while(newhead != NULL)
{
printf("%d\n",newhead->data);
newhead=newhead->next;
}

Line 26 should be while (newhead != NULL).
If you want to keep growing this, you could also review the purpose of each function, since add_node() and create() are doing almost the same thing, plus add_node() also prints the list, which could be the purpose of a separate function.

Related

creating a list of nodes with C

I want to createe a list of nodes that links to each other, I use head to remember the address of the first node, prev to link, and newdata to get the input, but it turns out that my head prev and newdata are all in the same address, can someone help me with this plz
typedef struct node
{
void* stdPtr;
struct node* link;
}NODE;
NODE* createNode(void* std)
{
NODE* nodePtr;
nodePtr=(NODE*)malloc(sizeof(NODE));
nodePtr->stdPtr=std;
nodePtr->link=NULL;
return nodePtr;
}
typedef NODE* nodePtr;
int main(void)
{
FILE* fin;
fin=fopen("input.txt","r");
//define
int i=0;
intPtr ID,grade;
STD* stdinfo;
nodePtr head=NULL;
nodePtr prev=(nodePtr)malloc(sizeof(NODE));
//nodePtr newdata=(nodePtr)malloc(sizeof(NODE));
prev=head;
//malloc space to ptr
ID=(intPtr)malloc(sizeof(int));
grade=(intPtr)malloc(sizeof(int));
stdinfo=(STD*)malloc(sizeof(STD));
//read student data and compare
while(fscanf(fin,"%d%d",&(stdinfo->ID),&(stdinfo->grade))!=EOF)
{
nodePtr newdata=(nodePtr)malloc(sizeof(NODE));
newdata=createNode(stdinfo);
if (prev==NULL)
{
prev=newdata;
head=prev;//為什麼只有在這裡=prev後面會跑掉?
}
printf("%d %d\n",*(int*)head,*(int*)prev);
if(prev->link!=NULL)
{
prev=prev->link;
}
prev->link=newdata;
}
fclose(fin);
return 0;
}
Important parts are missing (types, input.txt) to run your program which makes it harder to help you.
You create an instance of STD prior to the loop, then overwrite whatever data you store in it on each iteration and store the address of that one instance in each node. You need to create an instance of both NODE and STD per loop iteration (or change the definition of NODE so it can hold the STD data instead of a pointer to STD).
You use this pattern a couple of times which allocate data, then immediately leak the data by overwriting the pointer:
nodePtr prev=(nodePtr)malloc(sizeof(NODE));
prev=head;
...
nodePtr newdata=(nodePtr)malloc(sizeof(NODE));
newdata=createNode(stdinfo);
Here is more straight forward version to get you going:
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
void *stdPtr;
struct node* link;
} NODE;
NODE* createNode(void *std, NODE *prev) {
NODE *nodePtr = malloc(sizeof(NODE));
nodePtr->stdPtr=std;
nodePtr->link=prev;
return nodePtr;
}
void printNodes(NODE *tail) {
for(; tail; tail = tail->link) {
printf("%s\n", (const char *) tail->stdPtr);
}
}
int main(void) {
NODE *tail = NULL;
tail = createNode("hello", tail);
tail = createNode("world", tail);
printNodes(tail);
}

can't use a function with a 'pointer to pointer' input in another function. In C language

this code supposed to print : 'tree two one'
but it doesn't work. (the new_nod isn't added to the front of mylist)
anybody knows why? (actually in this code i wanted to use a function with a pointer to pointer input in another function but it didn't work(no changes applied to the mylist).
but it works when i'm using add_front function straightly in main.
#include <stdio.h>
#include <stdlib.h>
struct node{
char *word;
struct node *next;
};
struct node* create_node(char *str){
struct node *s;
s = (struct node *)malloc(sizeof(struct node));
if(s==NULL){
printf("couldn't malloc :(\n");
exit(-1);
}
s->word = str;
s->next = NULL;
return s;
}
void print_node(struct node *list){
struct node *current;
for(current = list; current !=NULL; current = current->next)
printf("%s ", current->word);
}
void add_front(struct node **list, struct node *new_node){
new_node->next= *list;
*list = new_node;}
void func(struct node*list, struct node*new_node){
add_front(&list, new_node);
}
int main()
{
struct node* mylist = create_node("one");
mylist->next = create_node("two");
struct node *new_node = create_node("tree");
func(mylist, new_node);
print_node(mylist);
}
Your add_front accepts a pointer to a pointer and other than missing a check for NULL is pretty much okay. But let's take a look at this:
void func(struct node*list, struct node*new_node){
add_front(&list, new_node);
}
What is add_front modifying here? The local pointer list. Which is just a copy of mylist in main.
So you haven't changed what mylist is pointing to.

New with nodes in C, how to fix the struct?

I have problems with understanding the whole concept of this. The major issue that confuses me is the the pointer inside a struct inside a struct... Basically what I understand is that I am wanting to create a chain of nodes.
When I run this program it crashes after two seconds. I believe there is something wrong with my structure in main.c, because I have created it by myself and as you can see I am really Bambi on thin ice over here...
main.c
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include "list.h"
// I guess my struct is not correct
static struct {
LIST node;
int item;
} node;
int main() {
list_create();
list_append(node.node, node.item);
}
list.h
typedef struct node* LIST;
LIST list_create (void);
void list_append (LIST l, int item);
list.c
struct node* list_create() {
struct node* head = (struct node*) malloc(sizeof (struct node));
head->next = NULL;
return head;
}
void list_append(struct node* n, int item)
{
/* Create new node */
struct node* new_node = (struct node*) malloc (sizeof (struct node));
new_node->item = item;
/* Find last link */
while (n->next) {
n = n->next;
}
/* Joint the new node */
new_node->next = NULL;
n->next = new_node;
}
At first, node is use for create a structure with data and in THIS data you have a pointer to another struct.
static struct {
LIST node;
int item;
} node;
Actually your structure is incorrect.
You must create at beginning a structure with your data for example :
static struct node{
int item;
};
then put a pointer to the similar structure but will not have same data =>
static struct node{
struct node *next;
int item;
};
You will can use this pointer to manipulate other & other structure.
I see another problem in your main :
You call the function "list_create()" which return a pointer to structure but you assign nothing.
you must create a pointer to struct then assign it like this :
int main() {
struct node *list;
list = list_create();
}
This code works completely (you can put it all in one C file; annotations in the code):
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
/* I removed the "static", because what we want is a type,
not a global static variable */
/* This "node" is our list-element. It has a pointer to a next element, and
some data, in this case, an int. */
typedef struct node {
struct node *next;
int item;
} node;
/* For convenience, another type, a pointer to a node. */
typedef node *LIST;
/* Creating a list is as simple as creating a node, and make the "next"
pointer NULL, you got this correct. */
struct node* list_create() {
struct node* head = (struct node*) malloc(sizeof (struct node));
head->next = NULL;
return head;
}
/* Nothing wrong in this append code. */
void list_append(struct node* n, int item)
{
/* Create new node */
struct node* new_node = (struct node*) malloc (sizeof (struct node));
new_node->item = item;
/* Find last link */
while (n->next) {
n = n->next;
}
/* Joint the new node */
new_node->next = NULL;
n->next = new_node;
}
/* I added this to make sure it works :) */
void print_list(LIST l) {
LIST tmp = l;
while (tmp) {
printf("%d\n", tmp->item);
tmp = tmp->next;
}
/* Here are some changes. I create a local LIST (which is basically a pointer
to a node, remember?) and use list_create to initialise it. Then, I call
list_append two times to put some extra data into it.
Works perfectly! */
int main() {
LIST myList = list_create();
list_append(myList, 10);
list_append(myList, 13);
print_list(myList);
}
You are calling list_create, but not using its result.

How to create head node

I think I got it wrong in newList. Typedef struct implementations must not be change. This is a lab assignment in my school.. Thanks in advance :)
#include<stdio.h>
typedef struct node *nodeptr;
struct node {
int item;
nodeptr next;
};
typedef nodeptr List;
List newList();
newList creates a header and returns a pointer to the header node
void display(List list);
void addFront(List list, int item);
List newList(){
List list;
list=(nodeptr)malloc(sizeof(List));
list->next=NULL;
return list;
} //I think my new list is incorrect..
void display(List list){
nodeptr ptr=list;
while(ptr!=NULL){
printf("%d",ptr->item);
ptr=ptr->next;
}
printf("\n");
}
void addEnd(List list, int item){
nodeptr temp, ptr;
temp=(List)malloc(sizeof(nodeptr));
temp->item=item;
temp->next=NULL;
if(list->next==NULL)
list=temp;
else{
ptr=list;
while(ptr->next!=NULL)
ptr=ptr->next;
ptr->next=temp;
}
}
I can't seem to add 10 from the list..
int main(void){
List list=newList();
addEnd(list,10);
display(list);
}
There are many ways you can go about this depending on what you actually want (because just creating a node doesn't make a lot of sense by itself). But generally you have three common options — create it on the stack, create that node in the global memory, or allocate it dynamically. Below are some examples.
On stack
#include <stdlib.h>
struct node {
int item;
struct node *next;
};
int main()
{
struct node head;
head.item = 0;
head.next = NULL;
/* Do something with the list now. */
return EXIT_SUCCESS;
}
In Global Memory
#include <stdlib.h>
struct node {
int item;
struct node *next;
};
static struct node head;
int main()
{
/* Do something with the list now. */
return EXIT_SUCCESS;
}
Dynamic Allocation
#include <stdlib.h>
#include <stdio.h>
struct node {
int item;
struct node *next;
};
int main()
{
struct node *head;
head = calloc(1, sizeof(struct node));
if (head == NULL) {
perror("calloc");
return EXIT_FAILURE;
}
/* Do something with the list now. */
return EXIT_SUCCESS;
}
You can read up on any of the above example in any introductory C book.
Hope it helps. Good Luck!

assignment from incompatible pointer type in linked list (C)

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.
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;
};
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
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.
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);

Resources