I'm learning on linked list so decided to do some exercise here I'm trying to show the data entered in the list. I've also include a comment for my understanding on the line
typedef struct node {
int num;
struct node *nextptr;
}Node;
Node *stnode;
void createNodeList(int n);
void displayList();
This are my created Node
void createNodeList(int n) {
Node *tmp;
int num = 1;
//allocate memory address to stnode
Node *stnode = (Node *)malloc(sizeof(Node));
if (stnode == NULL) {
printf("Memory error");
}
else {
printf("Input data for node 1:");
scanf("%d", &num);
//declare the stnode num field in struct as user input
stnode->num = num;
//declare the stnode address of the next node NULL (to be the last node)
stnode->nextptr = NULL;
//define the node name as tmp
tmp = stnode;
for (int i = 2; i <= n; i++) {
//allocate node to fnNode
Node *fnNode = (Node *)malloc(sizeof(Node));
if (fnNode == NULL) {
printf("Memory can not be allocated");
break;
}
else {
printf("Input data for node %d: ", i);
scanf("%d", &num);
//declare the node name fnNode num to store user input
fnNode->num = num;
//link the fnNode of nextptr to address null
fnNode->nextptr = NULL;
//link tmp node to fnNode
tmp->nextptr = fnNode;
tmp = tmp->nextptr;
}
}
}
}
This is to display them
void displayList() {
Node *tmp;
if (stnode == NULL) {
printf("List is empty");
}
else {
tmp = stnode;
while (tmp != NULL) {
printf("Data = %d\n", tmp->num);
tmp = tmp->nextptr;
}
}
}
After I've input 3 data, it should show the data I've input.
But it show "List is empty"
Thank you =)
Node *stnode = (Node *)malloc(sizeof(Node));
By this you are shadowing the global variable. That's why you retain no changes in the global variable. All you have done is used a local variable with same name as that of the global variable stNode.
That line should be
stnode = (Node *)malloc(sizeof(Node));
Don't cast the return value of malloc. It should be
stnode = malloc(sizeof(Node));
Or even more clearly
stnode = malloc(sizeof *stnode);
If you compile this program with -Wshadow option then you will
get warning regarding this shadowing. Enable all compiler warnings. It
helps.
Related
I am Working With Doubly Linked List & Implementing Them using C
I am using Turbo C++ as my Compiler
But it's Taking Two Constant Additional Nodes Every Time without Writing Code for It
The Same Code is Running in VS Code
But I Should Run it In Turbo C++
I tried Changing Systems, but it didn't Work
'''
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
struct Node
{
struct Node *prev;
int data;
struct Node *next;
} *head = NULL, *temp = NULL;
void insatbeg()
{
int item;
struct Node *ptr = NULL;
printf("\nEnter Item: ");
scanf("%d", &item);
ptr = (struct Node *)malloc(sizeof(struct Node *));
if (ptr == NULL)
printf("\nOverflow Occured");
else if (head == NULL)
{
ptr->data = item;
ptr->next = ptr->prev = NULL;
head = ptr;
}
else
{
ptr->prev = NULL;
ptr->data = item;
ptr->next = head;
head->prev = ptr;
head = ptr;
}
}
void display()
{
if (head == NULL)
printf("\nList is Empty");
else
{
temp = head;
while (temp != NULL)
{
printf("%d\t", temp->data);
temp = temp->next;
}
}
}
int main()
{
int loopvar = 1, switchvar;
clrscr();
code:
while (loopvar == 1)
{
printf("\nEnter 1 to Insert at First");
printf("\nEnter 2 to Display");
printf("\nEnter: ");
scanf("%d", &switchvar);
switch (switchvar)
{
case 1:
insatbeg();
break;
case 2:
display();
break;
default:
printf("\nEnter Properly: ");
goto code;
break;
}
printf("\nDo You Want to Continue: ");
scanf("%d", &loopvar);
}
getch();
}
'''
Also the Redundant Nodes Added Always are Constant
This memory allocation
ptr = (struct Node *)malloc(sizeof(struct Node *));
is invalid. You allocated a memory for the pointer type struct Node * while you need to allocate memory for an object of the type struct Node. So write
ptr = (struct Node *)malloc(sizeof(struct Node));
Also in this code snippet
else
{
ptr->prev = NULL;
ptr->data = item;
ptr->next = head;
head = ptr;
}
you forgot to set the data member prev of the head node. Write
else
{
ptr->prev = NULL;
ptr->data = item;
ptr->next = head;
head->prev = ptr;
head = ptr;
}
Pay attention to that the pointer temp1 is not used in your program.
If the code does not work as expected using the compiler Turbo C++ then try to initialize the pointer to the head node explicitly
struct Node
{
struct Node *prev;
int data;
struct Node *next;
} *head = NULL, *temp, *temp1;
I'm trying to print the linked list to which I prompt for user input.
This code below is not printing the whole list, only the last element at a time.
I don't seem to find the bug. Can you please take a look at it?
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node *next;
};
struct Node *head;
void Insert(int x) {
struct Node *temp = (struct Node *)malloc(sizeof(struct Node));
temp->data = x;
temp->next = NULL;
head = temp;
};
void Print() {
struct Node *temp = head;
printf("Linked list is: ");
while (temp != NULL) {
printf("%d ", temp->data);
temp = temp->next;
}
printf("\n");
};
int main() {
head = NULL;
int i, x;
for (i = 1; i <= 10; i++) {
if (i == 1) {
printf("Enter 1st number: \n");
} else if (i == 2) {
printf("Enter 2nd number: \n");
} else {
printf("Enter %dth number: \n", i);
}
scanf("%d", &x);
Insert(x);
Print();
}
}
temp->next = NULL; is the culprit. It should be temp->next = head;.
Another (more cornercase) issue is that your code fails to check for errors in malloc and scanf.
Edit in response to comment:
If you want to append (as opposed to prepend), you'll need to keep a tail pointer for forward traversal and then either use a dummy first node (avoids a branch) or special-case an insert to an empty list.
Example of both (with simplistic error handling via exit(1)) in one piece of code:
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node *next;
};
#define DUMMYFIRST 1 //change to 0 to compile the other variant
#if DUMMYFIRST
struct Node dummyfirst;
struct Node *head=&dummyfirst;
#else
struct Node *tail,*head=0;
#endif
void Insert(int x) {
struct Node *newnode = malloc(sizeof(struct Node));
//don't cast the result of malloc in C
//https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc
if(!newnode) { perror("malloc"); exit(1); }
newnode->data = x;
newnode->next = 0;
#if !DUMMYFIRST
if(!tail) tail = head = newnode;
else head->next = newnode;
#else
head->next = newnode;
#endif
head = newnode;
};
void Print() {
#if DUMMYFIRST
struct Node *newnode = dummyfirst.next;
#else
struct Node *newnode = tail;
#endif
printf("Linked list is: ");
while (newnode != NULL) {
printf("%d ", newnode->data);
newnode = newnode->next;
}
printf("\n");
};
int main() {
int i, x;
for (i = 1; i <= 10; i++) {
if (i == 1) {
printf("Enter 1st number: \n");
} else if (i == 2) {
printf("Enter 2nd number: \n");
} else {
printf("Enter %dth number: \n", i);
}
if(1!=scanf("%d", &x)) exit(1);
Insert(x);
Print();
}
}
A more library friendly approach to handling errors would be to propagate the error to the caller, i.e., instead of exiting with an error message right away, you'd change the return value from void to something indicating the error, e.g. so that the caller could check and decide what to do (print it, print it in a localized version, try a different algorithm...)
E.g.:
struct Node *Insert(int x) {
struct Node *newnode = malloc(sizeof(struct Node));
//don't cast the result of malloc in c
//https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc
if(!newnode) return NULL;
//...
};
//...
//calling code:
if(!Insert(x)) perror("Insert"),exit(1);
When you insert the new node, you do not link the rest of the list, instead of temp->next = NULL; you should write
temp->next = head;
To ensure defined behavior, you should check for memory allocation failure and invalid input.
Also remove the dummy ; after the function bodies.
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node *next;
};
struct Node *head;
int Insert(int x) {
struct Node *temp = malloc(sizeof(*temp));
if (temp) {
temp->data = x;
temp->next = head;
head = temp;
return 1;
} else {
return 0;
}
}
void Print(void) {
struct Node *temp = head;
printf("Linked list is: ");
while (temp != NULL) {
printf("%d ", temp->data);
temp = temp->next;
}
printf("\n");
}
int main() {
static char suffix[4][3] = { "th", "st", "nd", "rd" };
int i, x;
for (i = 1; i <= 10; i++) {
int suff = (i >= 1 && i <= 3) ? i : 0;
printf("Enter %d%s number:\n", i, suffix[suff]);
if (scanf("%d", &x) != 1) {
fprintf(stderr, "invalid or missing input\n");
break;
}
if (!Insert(x)) {
fprintf(stderr, "cannot allocate memory for Node\n");
return 1;
}
Print();
}
return 0;
}
im starting to learn data structures and i tried to making a simple program about a single linked list.
The problem is that when i call my display function (transversing the list) it doesn't give me an output? What is wrong with my code and how do i fix this?
This my program:
int main(){
int n;
printf(" Input the number of nodes : ");
scanf("%d", &n);
create(n);
printf("\n Data entered in the list : \n");
display();
}
void create(int n)
{
struct node *head=NULL;
int data, i;
head = (struct node *)malloc(sizeof(struct node));
if(head == NULL)
{
printf(" Memory can not be allocated.");
}
else
{
printf(" Input data for node 1 : ");
scanf("%d", &data);
head->data = data;
head->next = NULL;
for(i=1; i<n; i++) // Creating n nodes
{
struct node *current = (struct node *)malloc(sizeof(struct node)); // addnode
if(current == NULL)
{
printf(" Memory can not be allocated.");
break;
}
else
{
printf(" Input data for node %d : ", i);
scanf(" %d", &data);
current->data = data;
current->next = NULL;
head->next = current;
head = head->next;
}
}
}
}
My Traversing function:
void display(struct node *head)
{
struct node* ptr = head;
if(head == NULL)
{
printf(" List is empty.");
}
else
{
while(ptr != NULL)
{
printf(" Data = %d\n", ptr->data);
ptr = ptr->next;
}
}
}
The problem are lines in create()
head->next = current;
head = head->next;
this operation set head to current. Note that current->next is NULL. As result the entire content of the list is lost except the last element.
Just replace those lines with:
current->next = head;
head = current;
This will put the current node at the top of the list.
Remember to return head from create().
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node * next;
};
struct node * create(int n) {
struct node *head=NULL;
int data, i;
struct node * ptmp = NULL;
head = (struct node *)malloc(sizeof(struct node));
if(head == NULL) {
printf(" Memory can not be allocated.");
} else {
printf(" Input data for node 1 : ");
scanf("%d", &data);
head->data = data;
head->next = NULL;
ptmp = head;
for(i=1; i<n; i++) {
struct node *current = (struct node *)malloc(sizeof(struct node)); // addnode
if(current == NULL) {
printf(" Memory can not be allocated.");
break;
} else {
printf(" Input data for node %d : ", i);
scanf(" %d", &data);
#if 0
// insert first
current->data = data;
current->next = head;
head = current;
#else
// insrt last
current->data = data;
current->next = NULL;
ptmp->next=current;
ptmp = current;
#endif
}
}
}
return head;
}
void display(struct node *head)
{
struct node* ptr = head;
if(head == NULL) {
printf(" List is empty.");
} else {
while(ptr != NULL) {
printf(" Data = %d\n", ptr->data);
ptr = ptr->next;
}
}
}
int main() {
int n = 0;
printf(" Input the number of nodes : ");
scanf("%d", &n);
if (n<=0 || n > 6400) {
printf("Invalid input : %d (Enter value in range 0-6400)\n", n);
return 0;
}
struct node * head = create(n);
printf("\n Data entered in the list : \n");
display(head);
}
So, recently I had to create a linked list structure and I think got a function of creating it to work (hopefully), but now I have such simple problem as printing it into the console. I dont know whether there is something wrong with my structure that I created, or I do something wrong with printing. I would appreciate if somebody could find what is wrong with my code:
struct z { int a; struct z *next; };
struct z *head, *node, *next;
int data, x = 1;
int CreateList() {
printf("Enter 0 to end\n");
printf("Enter data no. %d: ", x);
x++;
scanf("%d", &data);
if (data == 0) return 0;
head = (struct z *)malloc(sizeof(struct z));
if (head == NULL) { printf("Error creating head"); return 0; }
node = head;
node->a = data;
node->next = NULL;
while (data) {
next = (struct z *)malloc(sizeof(struct z));
if (next == NULL) { printf("Error creating next node no. %d", x); return 0;}
node = next;
printf("Enter data no. %d: ", x);
x++;
scanf("%d", &data);
node->a = data;
node->next = NULL;
}
return 0;
}
int main() {
CreateList();
node = head;
while (node != NULL) {
printf("%d ", node->a);
node = node->next; //<=== crash on this line
}
return 0;
}
My output is always just the first entered int and then it all crashes on the marked line.
Your main loop uses the wrong variable:
int main(){
CreateList();
node = head;
while (next != NULL) {
printf("%d ", node->a);
node = node->next; //<=== crash on this line
}
return 0;
}
You should instead use node:
int main(){
CreateList();
node = head;
while (node != NULL) {
printf("%d ", node->a);
node = node->next; //<=== crash on this line
}
return 0;
}
Incidentally, head, node and next should be local variables, and head should be returned by CreateList().
CreateList() does not actually create the list correctly: nodes are not linked to the list as they are created, only the first node is stored in head.
Here is a corrected version that returns the list and the corresponding main function:
struct z { int a; struct z *next; };
struct z *CreateList(void) {
struct z *head, *node, *next;
int data, x = 1;
printf("Enter 0 to end\n");
printf("Enter data no. %d: ", x);
x++;
if (scanf("%d", &data) != 1 || data == 0)
return NULL;
head = malloc(sizeof(struct z));
if (head == NULL) {
printf("Error creating head");
return NULL;
}
node = head;
node->a = data;
node->next = NULL;
for (;;) {
printf("Enter data no. %d: ", x);
x++;
if (scanf("%d", &data) != 1 || data == 0)
break;
next = malloc(sizeof(struct z));
if (next == NULL) {
printf("Error creating next node no. %d", x - 1);
return NULL;
}
node->next = next;
node = next;
node->a = data;
node->next = NULL;
}
return head;
}
int main(void) {
struct z *head = CreateList();
struct z *node;
for (node = head; node != NULL; node = node->next) {
printf("%d ", node->a);
}
printf("\n");
return 0;
}
I think your problem is the global variables. Make them in the function, at least the node and the next. Create these on demand, for when you are actually adding the values. As a final tip, for this case, a do-while loop would make your code look cleaner than what it is right now, definitely you'd have less code repeat.
So I'm having trouble getting my program to print both the strings I input, or however many you want to put in the list, it always prints out the last string inputted multiple times. I am sorry about all the commented out code, most of it you don't need to read.
#include<stdio.h>
#include<stdlib.h>
struct node{
char *data;
struct node *next;
}*head;
typedef struct node NODE;
// Function prototypes
void append(char myStr[]);
void add( char myStr[] );
//void addafter(char myStr[], int loc);
void insert(char myStr[]);
int delete(char myStr[]);
void display(struct node *r);
int count();
// main function
int main()
{
int i;
struct node *n;
head = NULL;
char myStr[50];
while(1)
{
printf("\nList Operations\n");
printf("===============\n");
printf("1.Insert\n");
printf("2.Display\n");
printf("3.Size\n");
printf("4.Delete\n");
printf("5.Exit\n");
printf("Enter your choice : ");
if(scanf("%d", &i) <= 0)
{
printf("Enter only an Integer\n");
exit(0);
}
else
{
switch(i)
{
case 1:
printf("Enter the name to insert : ");
scanf("%50s", myStr);
insert(myStr);
break;
case 2:
if(head == NULL)
{
printf("List is Empty\n");
}
else
{
printf("Name(s) in the list are : ");
}
display(n);
break;
case 3:
printf("Size of the list is %d\n",count());
break;
case 4:
if(head == NULL)
printf("List is Empty\n");
else
{
printf("Enter the myStrber to delete : ");
scanf("%50s",myStr);
if(delete(myStr))
printf("%s deleted successfully\n",myStr);
else
printf("%s not found in the list\n",myStr);
}
break;
case 5:
return 0;
default:
printf("Invalid option\n");
}
}
}
return 0;
}
// Function definitions
void append(char myStr[])
{
struct node *temp,*right;
temp = (struct node *)malloc(sizeof(struct node));
temp->data = myStr;
right=(struct node *)head;
while(right->next != NULL)
{
right = right->next;
}
right->next = temp;
right = temp;
right->next = NULL;
}
// adding a node to the beginning of the linked list
void add( char myStr[] )
{
struct node *temp;
temp =(struct node *)malloc(sizeof(struct node));
temp->data = myStr;
// only one node on the linked list
if (head == NULL)
{
head = temp;
head->next = NULL;
}
else
{
temp->next = head;
head = temp;
}
}
void insert(char myStr[])
{
int c = 0;
struct node *temp;
temp = head;
if(temp == NULL)
{
add(myStr);
}
else
{
append(myStr);
}
}
int delete(char myStr[])
{
struct node *temp, *prev;
temp = head;
while(temp != NULL)
{
if(temp->data == myStr)
{
if(temp == head)
{
head = temp->next;
head = (*temp).next;
free(temp);
return 1;
}
else
{
prev->next = temp->next;
free(temp);
return 1;
}
}
else
{
prev = temp;
temp = temp->next;
}
}
return 0;
}
void display(struct node *r)
{
r = head;
if(r == NULL)
{
return;
}
while(r != NULL)
{
printf("%s ", r->data);
r = r->next;
if(r == NULL)
{
printf("\nOur linked list is finished!");
}
}
printf("\n");
}
int count()
{
struct node *n;
int c = 0;
n = head;
while(n != NULL)
{
n = n->next;
c++;
}
return c;
}
The problem seems to be that myStr at main function is a char[], so it's content is overritten every time you insert data. Notice that struct node data field is a char*, it's just pointing to myStr address.
Hope this help!
Your program has only one place to write your input, myStr.
With each input, myStr is erased and a something else is written to myStr.
The data member of all of the nodes, points to myStr. myStr will only contain the last input.
The display() function asks each node what is data. data points to myStr so each node prints the contents of myStr. myStr will only contain the last input so all the nodes print the last input.
To fix this, in the add() and append() functions, you need to give the data member some memory by using malloc(). Then copy the contents of myStr to the data member by using strcpy().
temp->data = malloc ( strlen ( myStr) + 1);
strcpy ( temp->data, myStr);
Do this instead of temp->data = myStr;
You will need #include<string.h>
The memory will need to be free()'d in the delete() function.
free(temp->data);
Do this before freeing temp
char *data
that variable from struct is always assigned with the address of myStr as its a pointer it would only show you the value of myStr