This question already has an answer here:
Delete element of linked list by a certain criterion
(1 answer)
Closed 7 years ago.
So the problem I'm running into is deleting a user-inputted string from a linked list full of strings.
I'm still having a few issues in understanding just precisely how linked lists work, so any explanation as to what I am doing wrong would be greatly appreciated!
Also, every other function seems to be working just fine, just having issues with the deleteItem function!
Edit - The problem I'm getting when I run the deleteItem function is just my terminal window crashing after getting hung up for a bit.
Here's my code:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct node
{
char name[50];
struct node *next;
}*head;
void display();
void insert();
void count();
void deleteItem();
int main(){
int choice = 1;
char name[50];
struct node *first;
head = NULL;
while(1){
printf("Menu Options\n");
printf("----------------\n");
printf("Please enter the number of the operation you'd like to do: \n");
printf("----------------\n");
printf("1. Insert\n");
printf("2. Display\n");
printf("3. Count\n");
printf("4. Delete\n");
printf("5. Exit\n");
printf("----------------\n");
scanf("%d",&choice);
switch(choice)
{
case 1:
insert();
break;
case 2:
display();
break;
case 3:
count();
break;
case 4:
if(head=NULL)
printf("The list is blank");
else
deleteItem();
break;
case 5:
return 0;
default:
printf("invalid option");
}
}
system("pause");
return 0;
}
void insert(){
char nameToInsert[50];
struct node *temp;
temp = head;
if(head == NULL){
head = (struct node *)malloc(sizeof(struct node));
printf("What's the name you wish to insert?\n");
scanf("%s", &nameToInsert);
strcpy(head->name, nameToInsert);
head->next = NULL;
}
else{
while(temp->next !=NULL){
temp = temp->next;
}
temp->next = malloc(sizeof(struct node));
temp = temp->next;
printf("What's the name you wish to insert?\n");
scanf("%s", &nameToInsert);
strcpy(temp->name, nameToInsert);
temp->next = NULL;
}
}
void display(){
struct node *temp;
temp = (struct node *)malloc(sizeof(struct node));
temp = head;
if(temp == NULL)
printf("The list is empty\n");
else{
printf("%s\n", temp->name);
while(temp->next != NULL){
temp = temp->next;
printf("%s\n", temp->name);
}
}
}
void count(){
struct node *temp;
int c =0;
temp = head;
while(temp!=NULL){
temp=temp->next;
c++;
}
printf("\n%d", c);
}
void deleteItem(){
char nameToDelete[50];
struct node *temp, *previous;
temp = head;
printf("What is the name you wish to delete?\n");
scanf("%s", nameToDelete);
while(temp->next != NULL){
temp = temp->next;
if(strcmp(nameToDelete, temp->name)==0){
previous = temp->next;
free(temp);
printf("%s was deleted successfully\n", nameToDelete);
}
}
}
I see the following issues:
You are not dealing with the case where the item to delete is at the head of the list.
The linked list is not restored to a good state after you free the node that contains the item.
You continue to iterate over the list even after you free the node that contains the item.
Here's a version that should work.
void deleteItem(){
char nameToDelete[50];
struct node *temp, *previous;
temp = head;
printf("What is the name you wish to delete?\n");
scanf("%s", nameToDelete);
// First, locate the node that contains the item.
for ( ; temp->next != NULL; temp = temp->next )
{
if(strcmp(nameToDelete, temp->name)==0)
{
break;
}
prev = temp;
}
// Now take care of deleting it.
if ( temp != NULL )
{
if ( temp == head )
{
head = temp->next;
}
else
{
prev->next = temp->next;
}
free(temp);
printf("%s was deleted successfully\n", nameToDelete);
}
}
Related
I want to add newnode behind headnode or others node but node not add whay Should i do?
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int val;
struct node *next;
} Node;
Node *head, *tail, *behind, *prev,*twonext;
Node *new_node(int val){
struct node *ptr = malloc(sizeof(*ptr));
if(ptr==NULL){
perror("malloc:");
printf("\nFailed to create a new node.\n");
return NULL;
}
ptr->val = val;
ptr->next = NULL;
return ptr;
}
Node *creatFirstNode(int val){
return head = tail = new_node(val);
}
void printList(void){
Node *np = head;
printf("\n----Value in Liked list----\n");
while(np){
printf("[%d], ", np->val);
np = np->next;
}
// printf("NULL\n");
}
void freeList(void){
while(head){
Node *np = head->next;
free(head);
head = np;
}
tail = NULL;
}
int main(void){
char cmd =' ';
int k;
printf("\n-------- Welcome to Linked List Program -----------\n\n");
do {
int v = 0;
int s = 0;
printf("\nAdd to 'h'ead or 't'ail or 'b'ehind value or 'p'rint or 'q'uit:");
scanf(" %c", &cmd);
fflush(stdin);
switch(cmd){
add headnode--------------------------------------------------------------------
case 'h':
printf("Enter value node head:");
scanf("%d", &v);
if(head == NULL){
creatFirstNode(v);
} else {
Node *np = new_node(v);
np->next = head;
head = np;
}
fflush(stdin);
printList();
break;
add tail node --------------------------------------------------------------------
case 't':
printf("Enter value node tail:");
scanf("%d", &v);
if(head == NULL){
creatFirstNode(v);
} else {
tail = tail->next = new_node(v);
}
fflush(stdin);
printList();
break;
add behind node I have problem here What Should i do?? -----------------------------------------------
case 'b':
printf("Enter node value:");
scanf("%d",&v);
Node *np = new_node(v);
printf("Adding value [%d] in new node:",v);
// behind = behind->next = new_node(v);
if(head == NULL)
{
printf("No node to insert behind:");
}
else
{
printf("\nAdd new node behind the value:");
scanf("%d", &s);
np = head;
while(np->val != s);
{
prev=np;
np =np->next;
}
twonext=np->next;
np->next=NULL;
np->next=twonext;
}
fflush(stdin);
printList();
break;
/*case 'p':
printList();
break;
*/
case 'q':
freeList();
printf("\nBye!\n");
getch();
break;
default:
printf("\n Invalid Input ");
}
}while(cmd != 'q' );
return 0;
}
Basically if you want to put a new node between others you've to link the prev->next with the new one and the new->next with the next node. That's all, here is a code example.
case 'b':
printf("Enter node value:");
scanf("%d",&v);
Node *np = new_node(v);
printf("Adding value [%d] in new node:",v);
// behind = behind->next = new_node(v);
if(head == NULL)
{
printf("No node to insert behind:");
}
else
{
printf("\nAdd new node behind the value:");
scanf("%d", &s);
Node *tmp = head; /*You need a tmp variable to go through the list*/
while(tmp->val != s && tmp != NULL);
{
prev=tmp; /*Save the prev node*/
tmp =tmp->next; /*Go through*/
}
if(tmp != NULL){
prev->next = np; /*Link the prev with the new*/
np->next = tmp; /*Link the new one with the subsequent*/
}
}
fflush(stdin);
printList();
break;
The idea is to be able to add a name to the end of the linked list when the user enters "1" and print and delete the first name in the linked list when the user enters "0". This is working if there is only 2 names in the linked list but anymore than 2 it only does the first name and last name, yet I cannot see my error.
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#define bool int
#define TRUE 1d
#define FALSE 0
typedef struct node{
char name[100];
struct node *next;
} Node;
Node *head;
void call(){
if(head == NULL){
printf("List is empty.\n");
}
else{
Node *temp;
printf("Calling %s\n", head->name);
if(head->next!=NULL){
temp = head->next;
free(head);
head = temp;
}
else{
head = NULL;
}
}
}
void add(char input[]){
Node *temp;
temp = (Node*)malloc(sizeof(Node));
strcpy(temp->name, input);
temp->next = NULL;
if(head == NULL){
head = temp;
}
else{
head->next = temp;
}
}
int main(){
start:;
int user_menu_answer;
char waste;
printf("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n");
printf("0) Call a customer\n");
printf("1) Add a customer\n");
printf("2) Quit\n");
printf("Please input your command \n");
printf("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n");
scanf("%d%c", &user_menu_answer, &waste);
//main menu options
if(user_menu_answer == 0){
call();
goto start;
}
else if (user_menu_answer == 1){
char input[23];
printf("Please give me the customers name: \n");
scanf("%[^\n]", input);
add(input);
goto start;
}
else if (user_menu_answer == 2){
printf("Quitting...");
return 0;
}
else{
printf("You did not enter a valid option, Please try again. \n");
goto start;
}
}
First MISTAKE:
void call(){
if(head == NULL){
printf("List is empty.\n");
}
else{
Node *temp;
printf("Calling %s\n", head->name);
if(head->next!=NULL){
temp = head->next;
free(head);
head = temp;
}
else{
free(head); //you don't free the memory if it's just one in the list
head = NULL;
}
}
}
Second mistake:
void add(char input[]){
Node *AuxHead; //create an aux to the head so you can move threw the list
Node *temp;
temp = (Node*)malloc(sizeof(Node));
if(temp!=NULL) //verify if it got allocated
{
strcpy(temp->name, input);
temp->next = NULL;
if(head == NULL){
head = temp;
}
else{
AuxHead=head; //pass the address of the head
while(AuxHead->next!=NULL) //catch the lest node of the list
AuxHead=AuxHead->next;
AuxHead->next = temp; //make the temp, the last of the list
}
}
}
Using double pointers first time to create and display linked list
#include "stdio.h"
#include "stdlib.h"
struct node
{
int data;
struct node * next;
};
void Insert(struct node **, int , int );
void display(struct node *);
int main()
{
int c, data, position;
struct node* head;
do{
printf("Enter a choice :\n");
printf("1. Add an element.\n");
printf("2. Del an element.\n3.Display List.\n");
printf("4.Delete linked list.\n5.Exit.\n");
printf("Your Choice :");
scanf("%d",&c);
switch(c){
case 1 :
printf("\nEnter data and position :\n");
scanf("%d %d",&data,&position);
Insert(&head,data,position);
break;
case 2 :
break;
case 3 :
printf("Linked List : \n");
display(head);
break;
case 4 :
break;
case 5 :
exit(0);
default :
printf("Invalid Choice.\n");
break;
}
}while(1);
return 0;
}
void Insert(struct node **ptrhead, int item, int position){
struct node *p,*newnode;
//node creation.
newnode = (struct node *)malloc(sizeof(struct node));
if (!newnode)
{
printf("Memory Error.\n");
return;
}
newnode->next = NULL;
newnode->data = item;
p = *ptrhead;
// Creates initial node
if (!(p->data))
{
p = newnode;
}
// insertion at beginning
if (position==1)
{
newnode->next = p;
p = newnode;
free(newnode);
}
// insertionn at middle or end.
else
{
int i=1;
while(p->next!=NULL && i<position-1){
p=p->next;
i++;
}
newnode->next = p->next;
p->next = newnode;
}
*ptrhead = p;
};
// Display Linked list
void display(struct node *head){
if (head)
{
do{
printf("%d\n", head->data);
head = head->next;
}while(head->next);
}
};
I will add functions for deletion and other operations later. Right now , I just want to insert and display fns to work . But output comes as infinitely running loop with wrong values. I cannot figure out what's wrong in my code , please help ?
Thanks in advance.
Not sure why somebody would be writing this type of C today, looks like maybe I'm doing your homework for you... In any case, you asked to fix your code, not rewrite it, so here's the minimum set of changes.
head should be initialized to NULL.
if (!(p->data)) is not right. That if statement should just be:
// Creates initial node
if (!p)
{
*ptrhead = newnode;
return;
}
Remove free(newnode);.
The insert at middle/end code could be
int i = 1;
struct node *n = p;
while (n->next != NULL && i<position - 1){
n = n->next;
i++;
}
newnode->next = n->next;
n->next = newnode;
The final insert function:
void Insert(struct node **ptrhead, int item, int position)
{
struct node *p, *newnode;
//node creation.
newnode = (struct node *)malloc(sizeof(struct node));
if (!newnode)
{
printf("Memory Error.\n");
return;
}
newnode->next = NULL;
newnode->data = item;
p = *ptrhead;
// Creates initial node
if (!p)
{
*ptrhead = newnode;
return;
}
// insertion at beginning
if (position == 1)
{
newnode->next = p;
p = newnode;
}
// insertionn at middle or end.
else
{
int i = 1;
struct node *n = p;
while (n->next != NULL && i<position - 1){
n = n->next;
i++;
}
newnode->next = n->next;
n->next = newnode;
}
*ptrhead = p;
}
Your print function isn't quite right, just make it:
// Display Linked list
void display(struct node *head)
{
while (head)
{
printf("%d\n", head->data);
head = head->next;
}
}
Please help values wont save once added into the list and nothing is printed as a result
#include <stdio.h>
#include <stdlib.h>
struct node{
char first[30];
char last[30];
char address[100];
char postal[6];
char number[10];
struct node* next;
};
typedef struct node node;
void print(node* root);
node* add(node* root);
void addinfo(node* root);
int main(){
node* root=NULL;
root=add(root);
print(root);
return 0;
}
Its supposed to add a new node at the end of the list then add values
node* add(node* root){
if(root==NULL){
root=(node*) malloc(sizeof(node));
addinfo(root);
root->next=NULL;
return root;
}
node* temp=root;
while(temp!=NULL){
temp=temp->next;
}
temp=(node*)malloc(sizeof(node));
addinfo(temp);
temp->next=NULL;
return root;
}
void print(node* root){
node* temp=root;
while(temp!=NULL){
printf("First Name: %s\n",temp->first);
printf("Last Name:%s\n",temp->last);
printf("Address:%s\n",temp->address);
printf("Postal%s\n",temp->postal);
printf("Phone Number:%s\n",temp->number);
temp=temp->next;
}
}
If I print in the function, the values print normally but once this functions ends all the values are gone.
void addinfo(node* root){
node* temp=root;
while(temp!=NULL){
temp=temp->next;
}
temp=malloc(sizeof(node));
printf("Please enter a name:");
gets(temp->first);
printf("Please enter a last name:");
gets(temp->last);
printf("Please enter an address:");
gets(temp->address);
printf("Please enter a postal code:");
gets(temp->postal);
printf("Please enter a phone number:");
gets(temp->number);
}
The simplest way of implementing what you want is keeping a pointer to the last item of a list:
typedef struct list {
node *first;
node *last;
} list;
Then you initialize a list with
list alist = { NULL, NULL };
and add items as follows:
void addNewNode(list *plist, node *pnode)
{
pnode->next = NULL;
if( plist->first == NULL)
plist->first = pnode;
else
plist->last->next = pnode;
plist->last = pnode;
}
fill the list:
while(there_is_something_to_read())
{
node *newnode = malloc(sizeof(node));
addInfo(newnode);
addNewNode(&alist, newnode);
}
note however, addInfo() should do just what its name says: add info to the node; no list manipulation:
void addinfo(node* pnode){
printf("Please enter a name:");
gets(pnode->first);
// .........
printf("Please enter a phone number:");
gets(pnode->number);
}
print it:
node *pnode;
for(pnode = alist.first; pnode != NULL; pnode = pnode->next)
printNode(pnode);
with
void printNode(node *pnode)
{
printf( "first name: %s\n", pnode->first);
//...
printf( "phone: %s\n", pnode->number);
printf( "\n");
}
The problem is in this code:
void addinfo(node* root){
node* temp=root;
while(temp!=NULL){
temp=temp->next;
}
temp=malloc(sizeof(node));
You carefully traverse the entire list until temp is NULL (which could be achieved more swiftly by writing temp = NULL; and then you overwrite the NULL with newly allocated memory, but don't hook the new node into the list.
This function cannot be used on an empty list. It can be revised to work on a non-empty list:
void addinfo(node *root)
{
if (root == NULL)
return; // Report error?
node *temp = root;
while (temp->next != NULL)
temp = temp->next;
temp->next = malloc(sizeof(node));
if (temp->next == NULL)
return; // Report error?
temp = temp->next;
temp->next = NULL;
…other code as before…
}
Wrote this program in C for linked Lists. I am getting an error in insert when trying to insert at the end of the linked list as a segmentation fault. All other cases are working such as inserting initially,inserting in between 2 elements,etc. Spent a lot of time pondering but couldnt figure out?
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
void insert();
void display();
void search();
void delete();
struct node{
int val;
struct node *next;
}*head;
int num,count=0;
void main()
{
char dec = 'E';
printf("Welcome to the Linked List C Program!\n");
head = NULL;
while(1){
printf("Make a Choice:\n");
printf("I.Insert\nD.Delete\nS.Search\nd.Display\nE.Exit\n");
scanf(" %c",&dec);
switch(dec){
case 'I':
insert();
break;
case 'D':
delete();
break;
case 'S':
search();
break;
case 'd':
display();
break;
case 'E':
exit(0);
break;
default:
printf("Wrong input Try Again!\n");
}
}
}
void insert(){
printf("Enter the number to insert:");
scanf("%d",&num);
struct node *temp;
struct node *newnode;
struct node *prev;
int c =0;
//temp = (struct node *)malloc(sizeof(struct node));
newnode = (struct node *)malloc(sizeof(struct node));
//prev = (struct node *)malloc(sizeof(struct node));
newnode->val = num;
if(head==NULL)
{
head = newnode;
head->next = NULL;
}
else
{
temp = head;
//searching whether linked list is in start or end
while(temp->val<num && temp !=NULL)
{
printf("Index:%d Value:%d Address:%p",c,temp->val,temp);
prev = temp;
temp = temp->next;
c++;
printf("TEST\n");
}
if(c==0)
{
head = newnode;
head->next = temp;
}
else
{
prev->next=newnode;
newnode->next=temp;
}
}
}
void display()
{
struct node *temp;
temp = (struct node *)malloc(sizeof(struct node));
temp = head;
while(temp != NULL)
{
printf("%d",temp->val);
temp = temp->next;
}
if(temp == NULL)
{
printf("Not present!");
}
}
void search()
{
printf("Enter the number tosearch for:\n");
scanf("%d",&num);
struct node *temp;
temp=head;
int c=0;
while(temp!=NULL)
{
if(temp->val==num)
{
printf("Present at position %d",c);
c++;
}
else if(temp == NULL)
{
printf("Not present!");
}
else
c++;
temp =temp->next;
}
}
void delete()
{
struct node *temp;
struct node *prev;
temp = head;
printf("Enter the value to delete:\n");
scanf("%d",&num);
int c=0;
while(temp!=NULL)
{
if(temp->val==num)
{
printf("Present at position %d",c);
printf("Deleting this element");
prev->next=temp->next;
free(temp);
c++;
}
else
c++;
prev = temp;
temp =temp->next;
}
if(temp == NULL)
{
printf("Not present!");
}
}
In your while loop, you're checking one of temp's members before checking that temp is not NULL:
while(temp->val<num && temp !=NULL)
reverse that:
while ((temp != NULL) && (temp->val < num))