How to get data from user for linked list - c

I tried to create linked list in C which will allow the user to insert data, print the list and exit from the program. I can insert the data and print the list one time but when I try to print the list again it shows list as empty. The address of the header has been changed to NULL.
#include <stdio.h>
#include <stdlib.h>
struct Node* head;
struct Node
{
int data;
struct Node* next;
};
void Insert(int x)
{
struct Node* temp=(struct Node*)malloc(sizeof(struct Node));
temp->data=x;
temp->next=head;
head=temp;
}
print()
{
printf("%d",head);
printf("\nthe list is\n");
while(head!=NULL)
{
printf("%d\t",head->data);
head=head->next;
}
}
int main()
{
//head=NULL;
int n,i,x,option;
do
{
printf("\n1.Insert 2.Print 3.Exit");
printf("\nenter option:");
scanf("%d",&option);
if(option==1){
printf("\nTotal no to be entered:");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("\nEnter the number:");
scanf("%d",&x);
Insert(x);
}}
else{
if(option==2){
print();
}
}
}while(option!=3);
}

Your print method changes the head pointer, so next time you access the list, head will point to null. You should use a different pointer for the iteration:
void print()
{
Node* iter = head;
printf("%d", iter);
printf("\nthe list is\n");
while(iter!=NULL)
{
printf("%d\t",iter->data);
iter=iter->next;
}
}

You are lopping over the linked list with the pointer head to the head of your list, so at the end of the loop, head reaches the end of the list and nothing remains to print.
To resolve the problem you need to keep head on its place (the head of the list) and loop with a second pointer loop_ptr
print()
{ Node* loop_ptr = head;// create a pointer to loop with
printf("%d",loop_ptr);
printf("\nthe list is\n");
while(loop_ptr!=NULL)
{
printf("%d\t",loop_ptr->data);
loop_ptr=loop_ptr->next;// at the end head points always to the head of your list
}
}
Nota Bene:
struct Node* next;
struct Node* head;
This is a bad practice when dealing with pointers. Unlike other data structures, a pointer must always properly initialized to avoid unexpected mess. In your case, you can do this:
struct Node* next= NULL;
struct Node* head= NULL;

Related

Linked list program only printing last two nodes of list

I wrote a program to create and print a single linked list. I have used structure pointer to structure pointer for modifying the list. When I print the list it only prints last two nodes added.
#include<stdio.h>
#include<stdlib.h>
struct node{
int data;
struct node *next;
};
struct node * createnode(int num){
struct node * n;
n=(struct node*)malloc(sizeof(struct node));
n->data=num;
n->next=NULL;
return n;
}
void createlist(struct node **head,int num){
struct node *temp=createnode(num);
*head=temp;
return;
}
void options(){
printf("Enter your choice\n");
printf("1.Add at end\n");
printf("2.Add at beginning\n");
printf("3.Add at location\n");
printf("4.Print list\n");
}
void add_end(struct node **head){
int info;
printf("Value: ");
scanf("%d",&info);
if(*head==NULL){
createlist(head,info);
return;
}
struct node *temp=createnode(info);
struct node **end=head;
while((*end)->next!=NULL){
(*end)=(*end)->next;
}
(*end)->next=temp;
}
void print2(struct node *head){
struct node * temp=head;
printf("\nList :");
while(temp!=NULL){
printf("%d ",temp->data);
temp=temp->next;
}
printf("\n");
}
int main(){
struct node *head=NULL;
createlist(&head,5);
int choice=0;
options();
scanf("%d",&choice);
while(1){
switch(choice){
case 1:add_end(&head);
break;
case 4:print2(head);
break;
default:exit(0);
}
options();
scanf("%d",&choice);
}
return 0;
}
Each time, I append 5 to 6 nodes at the end of list and when I print the list, it only prints last to nodes added.
I don't know it is wrong with add_end function or print function.
Your add_line routine incorrectly searches for the last node. The end variable is a pointer to pointer, so it is in a sense equivalent to the head parameter and it is not a temporary value, as it should be. Change the last lines to something like this:
void add_end(struct node **head){
...
struct node *end = *head;
while (end->next) {
end = end->next;
// Original line overwrites the 'head': (*end)=(*end)->next;
}
end->next=temp;
}

I got this code to inset an element at the end of the list.Segmentation fault

Hey guys i code this code for inserting an element at the end of the list
#include <stdio.h>
#include <stdlib.h>
struct node{
int data;
struct node *link;
};
struct node*head;
void insert(int x){
struct node*temp=(node*)malloc(sizeof(struct node));
temp->data=x;
temp->link=NULL;
struct node*temp1=head;
while(temp1->link!=NULL)
temp1=temp1->link;
temp1->link=temp;
};
void display(){
struct node*temp=head;
printf("LIst is:");
while(temp!=NULL){
printf("%d",temp->data);
temp=temp->link;
}
printf("\n");
};
int main()
{ head=NULL;
int n,i,x;
printf("Enter the number of elements:");
scanf("%d",&n);
for(i=0;i<n;i++){
printf("Enter the elements:");
scanf("%d",&x);
insert(x);
display();
}
}
Every time i compile it.It shows
Segmentation fault core dumped
please help
i don't know what wrong
am i accessing memory that “does not belong to me.
You assign head to temp1
struct node*temp1=head;
And at this moment head is NULL
then you dereference temp1 (NULL)
while(temp1->link!=NULL)
That's why you get a segfault.
head is NULL to start with. So when you do:
struct node*temp1=head;
while(temp1->link!=NULL)
^^^^^
you dereference NULL and the program crashes.
You need an extra if statement like to handle the case where head is NULL.
...
temp->link=NULL;
if (head == NULL)
{
head = temp;
return;
}
struct node*temp1=head;
...
BTW: In general it's a bad idea to have a global variable head.
To avoid a global variable you can do two things - either return the head pointer on every call to insert or pass the addsress of the head to the function. I prefer the last. It looks like:
void insert(struct node** pHead, int x){
struct node* temp=(node*)malloc(sizeof(struct node));
temp->data=x;
temp->link=NULL;
if (*pHead == NULL)
{
*pHead = temp; // Update head
return;
}
struct node* temp1 = *pHead;
while(temp1->link!=NULL)
temp1=temp1->link;
temp1->link=temp;
};
and call it like:
int main()
{
struct node* head=NULL; // Use a local variable
int n,i,x;
printf("Enter the number of elements:");
scanf("%d",&n);
for(i=0;i<n;i++){
printf("Enter the elements:");
scanf("%d",&x);
insert(&head, x); // Pass the address of head
....
}
}

linked list: how to return the whole linked list after insterting

I am trying to return the head of a linked list in the function Insert of the following program. However, it is failing with compilation error.
Can anyone please tell me what wrong I have done:
#include<stdio.h>
#include<stdlib.h>
struct ListNode
{
int data;
struct ListNode *next;
};
int ListLength(struct ListNode *head)
{
int count = 0;
struct ListNode *temp=head;
while(temp!=NULL)
{
count++;
temp=temp->next;
}
return count;
}
struct ListNode *Insert(struct ListNode *head, int value, int pos)
{
struct ListNode *temp,*curr;
curr=head;
int k=1;
temp=(struct ListNode *)malloc(sizeof(struct ListNode));
if(pos==1)
{
temp->data=value;
if(head==NULL)
{
temp->next=NULL;
head=temp;
}
else
{
temp->next=head;
head=temp;
}
}
else
{
while((curr!=NULL) && (k<pos))
{
k++;
curr=curr->next;
}
temp->data=value;
temp->next=curr->next;
curr->next=temp;
}
return head;
}
void printList(struct ListNode *head)
{
struct ListNode *temp;
temp=head;
while(temp!=NULL)
{
printf("%d",temp->data);
printf(" ");
temp=temp->next;
}
}
int main
{
struct ListNode *head=NULL;
//head = NULL;
head=Insert(head,10,1);
//Insert(head,11,2);
printList(head);
return 0;
}
I am trying to return the head of the new linked list after the insertion. I don't know where I am going wrong. Thanks in advance for the help.
(i) Firstly, include int main(void) as mentioned in the comments.
(ii) Next, with your current code, when you try printing the list, you are going to be in an infinite loop and get a stack overflow.
To avoid this, increment the temp to point to the next node after each print.
So your print function should look like:
void printList(struct ListNode *head)
{
struct ListNode *temp;
temp=head;
while(temp!=NULL)
{
printf("%d",temp->data);
printf(" ");
temp=temp->next; // this line is required
}
}
(iii) And in your main function, call the printList with an argument, that is the head of the node like this:
printList(head);
(iv) And don't forget to return the count in your finding the length of the list function. Add the return statement at the end of your ListLength function:
return count;
(v) Your current code does not handle a case when head is NULL, and user wants to insert at a position greater than 1. Or more generally, when a user wants to insert at a position that is greater than the current list's length.
While you trust such an input would not be given, always handle such exceptions (you would probably get a SEGMENTATION FAULT here when trying to access memory of null nodes).
To handle this, you can add a check at the start of the Insert function like,
int lenList = ListLength(head);
if (lenList < pos)
{
printf("Please provide a position less than %d to insert", lenList);
return 0; // don't proceed with inserting node with NULL pointers
}
If head is declared global you don't have to return it. (Sorry, my answer is short)

Linked-list entering node at end each time while get input from user but something went wrong with any method

While trying to append node at the end of the linked list for each input given by user, there is something wrong with this code. I'm not getting it why this is happening? Could someone please point out what the problem is? If any one knows, please suggest me something to fix this bug?
#include <stdio.h>
//structure with two fields
struct node
{
int data;
struct node *next;
};
// data type definition
typedef struct node node;
//pointer to node which initially set to NULL
node *head=NULL;
//fucntion create and display
void create(int num);
void display();
main()
{
int n,i,num;
printf("enter the no of nodes : ");
scanf ("%d",&n);
for(i=0;i<n;++i)
{
printf("enter the data : ");
scanf("%d",&num);
create(num);
}
display();
}
//function create
void create(int num)
{
printf("\n");
if(head==NULL)
{
node *temp=(node*)malloc(sizeof(node));
temp->data=num;
temp->next=head;
head=temp;
}
else
{
node *temp1=head;
while(temp1!=NULL)
{
temp1=temp1->next;
}
node *ptr=(node*)malloc(sizeof(node));
ptr->data=num;
ptr->next=temp1->next;
temp1->next=ptr;
}
}
//function display()
void display()
{
node *temp;
temp=head;
printf("list is : ");
while(temp!=NULL)
{
printf("%d->",temp->data);
temp=temp->next;
}
}
This should help you!
void create(int num)
{
printf("\n");
if(head==NULL)
{
node *temp=(node*)malloc(sizeof(node));
temp->data=num;
temp->next=head;
head=temp;
}
else
{
node *temp1=head;
//Modified the condition to traverse till the last node, not the end of it
while(temp1->next != NULL)
{
temp1=temp1->next;
}
node *ptr=(node*)malloc(sizeof(node));
ptr->data=num;
ptr->next=temp1->next;
temp1->next=ptr;
}
}
(Note: there might be other issues in the program, I have not run it)
I'm looking at this part of the create function
node *temp1=head;
while(temp1!=NULL)
{
temp1=temp1->next;
}
node *ptr=(node*)malloc(sizeof(node));
ptr->data=num;
ptr->next=temp1->next;
temp1->next=ptr;
And it seems like you iterate over the list until you reach the end. At which point temp1 == NULL. But then you try to access temp1->next which should be an unaccessible memory (remember that you have just set it to NULL in the previous while-loop.
A debugger can help you with this situations (or even printing some information around). A widely used debugger is gdb.
(Note: there might be other issues in the program, I have not run it)

unable to display the entire link list only displays the last element in link list in c

i am trying to create a singly link list but while displaying it stores the last entered value only the first entered value goes missing
for ex:
if i am entering 1 node or 1 element it works fine but as soon as i enter 2 elements it displays only the last entered value the first value goes missing.
#include<stdio.h>
#include<stdlib.h>
struct node
{
int data;
struct node *next;
};
struct node *create(struct node *head,int data)
{
if(head->next==NULL)
{
head->data=data;
head->next=NULL;
}
else
{
head=head->next;
head->data=data;
head->next=NULL;
}
return head;
}
void display(struct node * head)
{
while(head!=NULL)
{
printf("%d",head->data);
head=head->next;
}
}
main()
{
struct node *head=(struct node*)malloc(sizeof(struct node)),*head1;
int n,data,i;
printf("\n enter how many elements ");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("enter data");
scanf("%d",&data);
head=create(head,data);
}
display(head);
}
That is because head in main() is re-assigned to the new, last, element all the time.
There will only ever be one element in your linked list since the only time an element is created is in the first line in your main method.
In the create() function, malloc() a new element and assign head->next to its value, then populate it with data.
struct node *create(struct node *element, int data)
{
if (element)
{
while(element->next)
{
element = element->next;
}
element->next = malloc(sizeof(struct node));
element = element->next;
}
else
{
element = malloc(sizeof(struct node));
}
element->data = data;
return element;
}
Now, do not reassign head to the returned value from the call to create() in main(), but if you later want to optimize for some reason, you could always save a tail pointer and use that as the parameter to create(), so that you will not have to traverse the entire list each time.
Also, not that I haven't compiled this, so there may be some syntactic errors...
Use the below linked list create function and get the required result.
To solve that you need to assign struct node *head=NULL and use the below create function.
Create Function:
struct node *create(struct node *head,int value)
{
struct node *temp;
/* updated code start */
if(head == NULL)
{
head=(struct node *)malloc(sizeof(struct node));
temp->data=value;
temp->next=NULL;
}
else
{
/*Updated code ends */
temp=head;
while(temp->next != NULL)
temp=temp->next;
temp->next=(struct node *)malloc(sizeof(struct node));
if (temp->next !=NULL)
{
temp=temp->link;
temp->data=value;
temp->next=NULL;
}
}
return head;
}
Update:
Due to memory allocation unable to find whether the first position is empty or not.
we can also do something in for statement before calling the create function, like
if(i==0)
{
head->data=value;
head->next=NULL;
continue;
}
The above code is also one of the way to do the same thing with the existing code.

Resources