i'm creating a phonebook system in c using single linked list it seems that everything is working well but the delete option always giving me an error and i don't know how to fix it so i hope someone can tell what is problem in the code and show me a code that can modify the name or the number in this code
#include<stdio.h>
#include<stdlib.h>
struct node
{
char firstname[20];
char lastname[20];
long int number;
struct node *next;
};
struct node *head=NULL;
struct node *getnode()
{
return((struct node *)malloc(sizeof(struct node)));
}
void display(struct node *head)
{
struct node *temp;
temp=head;
while(temp!=NULL)
{
printf("%s\n",temp->firstname);
printf("%s\n",temp->lastname);
printf("%d\n",temp->number);
temp=temp->next;
}
}
void insert()
{
struct node *temp,*newnode;
newnode=getnode();
temp=head;
while(temp->next!=NULL)
{
temp=temp->next;
}
printf("Enter First name:\n");
scanf("%s",&newnode->firstname);
printf("Enter Last name:\n");
scanf("%s",&newnode->lastname);
printf("Enter number:\n");
scanf("%d",&newnode->number);
temp->next=newnode;
newnode->next=NULL;
display(head);
}
struct node *create()
{
struct node *temp,*newnode;
if(head!=NULL)
insert();
else
{
newnode=getnode();
head=newnode;
temp=head;
printf("Enter First name:\n");
scanf("%s",&newnode->firstname);
printf("Enter Last name:\n");
scanf("%s",&newnode->lastname);
printf("Enter number:\n");
scanf("%d",&newnode->number);
newnode->next=NULL;
display(head);
}
}
void search()
{
struct node *temp;
char *first,*last;
temp=head;
printf("Enter name to be searched:\n");
scanf("%s",&first);
scanf("%s",&last);
while((temp->firstname==first)&&(temp->lastname==last))
{
temp=temp->next;
}
printf("%s\n",temp->firstname);
printf("%s\n",temp->lastname);
printf("%d\n",temp->number);
}
void del()
{
struct node *pretemp,*temp;
char *f,*l;
temp=head;
pretemp=head->next;
printf("Enter name :");
scanf("%s",&f);
scanf("%s",&l);
while(temp!=NULL){
if((pretemp->firstname==f)&&(pretemp->lastname==l))
{
printf("%s ",temp->firstname);
printf("%s ",temp->lastname);
printf("%s ",temp->number);
temp=pretemp->next;
delete pretemp;
break;
}
else
{
temp=temp->next;
pretemp=pretemp->next;
}
}
int main()
{
int op,ch;
do{
printf("-------Welcome--------\n");
printf("1.Create\n2.Display\n3.Delete\n4.Search\n");
printf("Enter your choice:");
scanf("%d",&ch);
switch(ch)
{
case 1: create();
break;
case 2: display(head);
break;
case 3: del();
break;
case 4:search();
break;
}
printf("Do you want to quit ? 1 for no / 0 for yes:");
scanf("%d",&op);
}while(op);
return 0;
}
this is the error
I had made the following changes in your search and delete function
The first and last buffer in both search and delete function were not allocated memory before using them in scanf. This will cause run-time error
The way you were catching user input for first and last name in scanf was also improper
In search and delete function I modified the string comparison. To compare to string you need use strncmp function. Using == will check the address of first byte.
In search function you were not checking end of list.
In del function I have changed printf("%s ", temp->number) to printf("%d ", temp->number)
void search()
{
struct node *temp;
char first[20], last[20];
temp = head;
printf("Enter name to be searched:\n");
scanf("%s", first);
scanf("%s", last);
while (temp != NULL && ((strncmp(temp->firstname, first, 20) != 0) && (strncmp(temp->lastname, last, 20) != 0)))
{
temp = temp->next;
}
if (temp != NULL) {
printf("%s\n", temp->firstname);
printf("%s\n", temp->lastname);
printf("%d\n", temp->number);
}
}
void del()
{
struct node *pretemp, *temp;
char first[20], last[20];
temp = head;
pretemp = head->next;
printf("Enter name :");
scanf("%s", first);
printf("Enter Last name:");
scanf("%s", last);
while (temp != NULL) {
if((strncmp(temp->firstname, first, 20) != 0) && (strncmp(temp->lastname, last, 20) != 0))
{
printf("%s ", temp->firstname);
printf("%s ", temp->lastname);
printf("%d ", temp->number);
temp = pretemp->next;
delete pretemp;
break;
}
else
{
temp = temp->next;
pretemp = pretemp->next;
}
}
}
I made some changes in your code, you can find comment in code bellow.
It is compiled and likend under linux ubuntu 18.04 and it works now.
Basicaly, when you use scanf(" %s ", astr), 'astr' should have enough space to accept input.
#include<stdio.h>
#include<stdlib.h>
struct node
{
char firstname[20];
char lastname[20];
long int number;
struct node *next;
};
struct node *head=NULL;
struct node *getnode()
{
return((struct node *)malloc(sizeof(struct node)));
}
void display(struct node *head)
{
struct node *temp;
temp=head;
while(temp!=NULL)
{
printf("%s\n",temp->firstname);
printf("%s\n",temp->lastname);
printf("%ld\n",temp->number); /* number is long int */
temp=temp->next;
}
}
void insert()
{
struct node *temp,*newnode;
newnode=getnode();
temp=head;
while(temp->next!=NULL)
{
temp=temp->next;
}
printf("Enter First name:\n");
scanf("%s",newnode->firstname);
printf("Enter Last name:\n");
scanf("%s",newnode->lastname);
printf("Enter number:\n");
scanf("%ld",&newnode->number);
temp->next=newnode;
newnode->next=NULL;
display(head);
}
struct node *create()
{
struct node *temp,*newnode;
if(head!=NULL)
insert();
else
{
newnode=getnode();
head=newnode;
temp=head;
printf("Enter First name:\n");
scanf("%s",newnode->firstname);
printf("Enter Last name:\n");
scanf("%s",newnode->lastname);
printf("Enter number:\n");
scanf("%ld",&newnode->number);
newnode->next=NULL;
display(head);
}
}
void search()
{
struct node *temp;
char first[20], last[20]; /* space for input */
temp=head;
printf("Enter name to be searched:\n");
scanf("%s",first); /* you dont need '&' operator for string*/
scanf("%s",last);
while((temp->firstname==first)&&(temp->lastname==last))
{
temp=temp->next;
}
printf("%s\n",temp->firstname);
printf("%s\n",temp->lastname);
printf("%ld\n",temp->number); /* number is long int */
}
void del()
{
struct node *pretemp,*temp;
char f[20],l[20]; /* you need a space to store input */
temp=head;
pretemp=head->next;
printf("Enter name :");
scanf("%s",f); /* you dont need '&' operator to access a string */
scanf("%s",l);
while(temp!=NULL){
if((pretemp->firstname==f)&&(pretemp->lastname==l))
{
printf("%s ",temp->firstname);
printf("%s ",temp->lastname);
printf("%ld ",temp->number); /* 'number' is long int */
temp=pretemp->next;
free(pretemp); /* 'delete' is c++ operator, not C */
break;
}
else
{
temp=temp->next;
pretemp=pretemp->next;
}
} /* missing curly bracket */
}
int main()
{
int op,ch;
do{
printf("-------Welcome--------\n");
printf("1.Create\n2.Display\n3.Delete\n4.Search\n");
printf("Enter your choice:");
scanf("%d",&ch);
switch(ch)
{
case 1: create();
break;
case 2: display(head);
break;
case 3: del();
break;
case 4:search();
break;
}
printf("Do you want to quit ? 1 for no / 0 for yes:");
scanf("%d",&op);
}while(op);
return 0;
}
Related
I have a school project in which I have to make such a menu to handle a double linked list with float content, but i have massive trouble making it double-linked,and after some debugging it looks like its all (*H)->next...'s fault, (apart from mine),when i get a new_node, i make its 'next' part point to the head's adress, and head's 'prev' part point to the new_node's adress, and then making head's adress that of new_node, thus head, becoming actually the head.
#include <stdio.h>
#include <stdlib.h>
struct node {
char data;
struct node *next;
struct node *prev;
};
void Create(struct node **H,char val) {
struct node *new_node;
new_node=malloc(1*sizeof(struct node));
new_node->data=val;
if(new_node==NULL){
printf("RIP");
return;
}else{
new_node->next=*H;
new_node->prev=NULL;
(*H)->prev=new_node;
}
}
void Delete(struct node **H){
if(*H!=NULL){
struct node *temp = H;
temp->next=NULL;
printf("Deleting last element with value: %c\n",(*H)->data);
*H=(*H)->next;
free(temp);
}else{
printf("Empty list.\n");
}
}
void DisplayF(struct node *H){
int i = 0;
if(H==NULL){printf("Empty list\n");return;};
while(H!=NULL){
i++;
printf("Element #%d: %c\n",i, H->data);
H=H->next;
}
return;
}
void DisplayB(struct node *H){
int i = 0;
if(H==NULL){printf("Empty list\n");return;};
while(H!=NULL){
i++;
printf("Element #%d: %c\n",i, H->data);
H=H->prev;
}
return;
}
void Search(struct node *H,char val){
int i = 0;
while(H!=NULL){
i++;
if(H->data==val){
printf("Character '%c' was found in element %d\n",H->data,i);
return;
}
H=H->next;
}
printf("The value you are looking for does not exist.\n");
}
int main(){
struct node *head=NULL;
int inp;
char d;
do{
printf("1.Create\n2.Delete\n3.Display\n4.Search\n0.Exit\n");
scanf("%d",&inp);
switch (inp){
case 1:
printf("Enter the new node's character value: ");
scanf(" %c",&d);
Create(&head,d);
break;
case 2:
Delete(&head);
break;
case 3:
DisplayF(head);
break;
case 4:
DisplayB(head);
case 5:
printf("What character do you want to search for? ");
scanf(" %c",&d);
Search(head,d);
break;
case 0:
exit(0);
default:
printf("Enter a valid option from the menu below:\n");
break;
}
}while(inp!=0);
return 0;
}
So I had a problem with the "String name" I fixed it, now I would like to
add a function that's removes the node by its ID, so I tried to make a function that locates the node with the requested ID, It did not go well because it does not track the ID I entered.
Here is the full code:
#include <stdlib.h>
#include <stdio.h>
typedef struct stringData {
int id;
char *name;
int payment;
struct stringData *next;
} Node;
Node *addEmployee(int id, char *name, int payment) {
Node *newNode = (Node *)malloc(sizeof(Node));
newNode->id = id;
newNode->name = strdup(name);
newNode->payment = payment;
newNode->next = NULL;
return newNode;
}
void insert(Node **link, Node *newNode) {
newNode->next = *link;
*link = newNode;
}
void removeEmployee(Node *head, int id){
while (head != NULL){
head = head->next;
if(head ->id == id){
printf("The employee exists.");
}
printf("The employee does not exists.");
}
}
void printList(Node *head) {
while (head != NULL) {
printf("----------------------------------\n");
printf("Name: %s\n", head->name);
printf("ID: %d\n", head->id);
printf("Payment: %d\n", head->payment);
printf("----------------------------------\n");
head = head->next;
}
}
int main(void)
{
int id;
char name[42];
int payment;
int input;
Node *head = NULL;
Node *tail = NULL;
Node *n;
n = addEmployee(1, "Dor", 5000);
insert(&head, n);
tail = n;
n = addEmployee(2, "David", 10000);
insert(&head, n);
tail = n;
printList(head);
removeEmployee(head, 2);
while((input != 4)){
printf("\nPlease select 1 option:\n1) Add an employee - type 1\n2) Remove an employee - type 2\n3) Show a list of employees - type 3\n4) Exit - type 4\n");
scanf("%d", &input);
switch(input){
case 1:
printf("\nPlease enter the employee's id: ");
scanf("%d", &id);
printf("\nPlease enter the employee's name: ");
scanf("%41s",name);
printf("\nPlease enter the employee's payment: ");
scanf("%d", &payment);
n = addEmployee(id, name, payment);
insert(&head, n);
tail = n;
break;
case 2:
printf("Please enter the ID of the employee you would like to remove: ");
scanf("%d", &id);
break;
case 3:
printList(head);
break;
case 4:
printf("Good-bye");
break;
default:
printf("This is not an option!");
break;
}
}
return 0;
}
I do not know how to get into it, I'm not that familiar with this subject so It would be very helpful to also see some examples.
If I insert an element before an existing element then the last two elements keeps printing infinitely. For example, if 10 20 30 are the existing elements and now if I want to insert 40 before 30(so that new list becomes 10 20 40 30) then 40 & 30 prints for an infinite number of times.
Thanks in advance.
#include<stdio.h>
#include<stdlib.h>
typedef struct node
{
int data;
struct node *next;
}list;
list *start=NULL;
list *create(list *);
list *display(list *);
list *insert_before(list *);
int main()
{
int n;
printf("1: Create list\n");
printf("2: Display\n");
printf("3: Insert before an existing element\n);
for(;;)
{
printf("Enter your choice: ");
scanf("%d",&n);
switch(n)
{
case 1:start=create(start);
printf("\nList created successfully\n");
break;
case 2:start=display(start);
break;
case 3:start=insert_before(start);
break;
default:printf("Wrong input!!!");
exit(0);
}
}
}
list *create(list *start)
{
list *new_node, *ptr;
int num;
printf("Enter data: ");
scanf("%d",&num);
new_node=(list *)malloc(sizeof(list));
new_node->data=num;
if(start==NULL)
{
start=new_node;
new_node->next=NULL;
}
else
{
ptr=start;
while(ptr->next!=NULL)
{
ptr=ptr->next;
}
ptr->next=new_node;
new_node->next=NULL;
}
return start;
}
list *display(list *start)
{
list *ptr;
if(start==NULL)
{
printf("Empty list");
return start;
}
else
{
ptr=start;
while(ptr->next!=NULL)
{
printf("%d\n",ptr->data);
ptr=ptr->next;
}
}
return start;
}
list *insert_before(list *start)
{
int num,search,flag=0;
list *new_node, *ptr, *prev;
ptr=start;
printf("Enter the number before whom new data is to be inserted: ");
scanf("%d",&search);
while(ptr!=NULL)
{
prev=ptr;
if(ptr->data==search)
{
flag=1;
break;
}
ptr=ptr->next;
}
if(flag==1)
{
printf("\nEnter the new data to be entered");
scanf("%d",&num);
new_node=(list *)malloc(sizeof(list));
new_node->data=num;
prev->next=new_node;
new_node->next=ptr;
}
else
{
printf("Entered data cannot be found");
}
return start;
}
In the function insert_before you should be checked if the first item is the searched and then analyse the other case. Well i did some change and this is the modificated code for in the funtion:
list *insert_before(list *start){
int num,search,flag=0;
list *new_node, *ptr, *prev;
ptr=start;
printf("Enter the number before whom new data is to be inserted: ");
scanf("%d",&search);
if(start != NULL && start->data == search){
printf("Enter the new data to be entered: ");
scanf("%d",&num);
new_node=(list *)malloc(sizeof(list));
new_node->data=num;
new_node->next = start;
if(start->next == start)
start->next=new_node;
else{
ptr=start;
while(ptr->next!=start) ptr=ptr->next;
ptr->next=new_node;
}
start=new_node;
}
else{
while(!flag && ptr->next!=start){
prev=ptr;
if(ptr->next->data==search) flag=1;
ptr=ptr->next;
}
if(flag==1){
printf("Enter the new data to be entered: ");
scanf("%d",&num);
new_node=(list *)malloc(sizeof(list));
new_node->data=num;
prev->next=new_node;
new_node->next=ptr;
}
else
printf("Entered data cannot be found\n");
}
return start;
}
I have created here a C Program in TurboC++. This simple program goal is to just create a linked list, insert every element at the end of the list and then print the value of the nodes.(Edited The program is somewhat changed to make it easier for me to understand but still the problem of nodes not being priniting exists)
The problem is, some of the node elements are not printing
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<ctype.h>
#include<conio.h>
struct node
{
int data;
struct node *link;
};
typedef struct node ND;
void main()
{
ND *start,*current,*temp;
start=NULL;
do
{
temp=(ND*)malloc(sizeof(ND));
printf("\n Enter Node Value");
scanf(" %d",&temp->data);
temp->link=NULL;
if(start==NULL)
{
start=current=temp;
}
else
{
current->link=temp;
current=temp;
}
fflush(stdin);
printf("\nDo You Want TO Continue?(Y/N)");
}while(toupper(getchar())!='N');
current=start;
printf("\nThe Elements OF Linked List ARE:");
while(current!=NULL)
{
printf(" %d",current->data);
current=current->link;
}
}
You printing list from wrong element. You should start from head.
like:
temp1 = head;
while(temp1!=NULL)
{
printf(" %d",temp1->data);
temp1=temp1->link;
}
By the way your head element will be always NULL.
Here is correct way to add elements to list:
if (head == NULL)
{
head = temp;
}
else
{
temp1 = head;
while (temp1->link != NULL)
{
temp1 = temp1->link;
}
temp1->link = temp;
}
The program is now working correctly i have made some changes to make this program easier to understand.Here's the code:
#include<stdio.h>
#include<conio.h>
struct node
{
int data;
struct node *link;
};
typedef struct node ND;
void main()
{
ND *head,*tail,*temp1;
int n;
char ch;
printf("\nEnter Data?(y/n)\n");
scanf(" %c",&ch);
fflush(stdin);
if(ch=='y' || ch=='Y')
{
tail=(ND*)malloc(sizeof(ND));
printf("\n Enter Node Value");
scanf(" %d",&n);
tail->data=n;
tail->link=NULL;
head=tail;
printf("\nDo You Want TO Continue?(Y/N)");
scanf(" %c",&ch);
fflush(stdin);
}
while(ch=='y' || ch=='Y')
{
printf("\n Enter Node Value");
scanf(" %d",&n);
tail->link=(ND*)malloc(sizeof(ND));
tail->link->data=n;
tail->link->link=NULL;
tail=tail->link;
printf("\nEnter More Data?(y/n)\n");
scanf(" %c",&ch);
fflush(stdin);
}
printf("\nElements Of Linked List Are:");
temp1=head;
while(temp1!=NULL)
{
printf(" %d",temp1->data);
temp1=temp1->link;
}
printf("\n");
fflush(stdout);
getch();
}
I have written the following program but the problem is in Delete function.Whenever i am trying to delete the value at first position.The whole list is lost don't know why.If i try to display list after that then some garbage values are printed.The function is working perfectly for other positions.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
struct Student
{
int rno;
char name[20];
struct Student *next;
struct Student *prev;
};
void Display(struct Student *head)
{
assert(head!=NULL);
while(head!=NULL)
{
printf("%d\t%s\t",head->rno,head->name);
head=head->next;
}
}
struct Student *Insert(struct Student *head,const int position,const int rno,const char name[])
{
//printf("%s\n",__FUNCTION__);
struct Student *temp=(struct Student *)malloc(sizeof(struct Student));
struct Student *traverse=head;
int pos=position;
if(temp==NULL)
exit(-1);
temp->rno=rno;
strcpy(temp->name,name);
temp->next=NULL;
temp->prev=NULL;
// printf("%s\n",__FUNCTION__);
if(pos==1)
{
if(head==NULL)
{
head=temp;
}
else
{
temp->next=head;
head->prev=temp;
head=temp;
}
}
else
{
for(traverse=head,pos=position;traverse->next!=NULL&&pos-2!=0;traverse=traverse->next,pos--);
if(traverse==NULL || pos-2!=0)
{
printf("Invalid Position");
}
else
{
temp->next=traverse->next;
if(temp->next!=NULL)
temp->next->prev=temp;
temp->prev=traverse;
traverse->next=temp;
}
}
return head;
}
void DeleteAll(struct Student *head)
{
struct Student *temp=head;
while(temp->next!=NULL)
{
head=head->next;
free(temp);
temp=head;
}
free(temp);
}
void Delete(struct Student *head,int pos)
{
assert(head!=NULL);
struct Student *temp=head;
struct Student *traverse=head;
int position=pos;
if(position==1)
{
if(head->next!=NULL)
head=head->next;
head->prev=NULL;
temp->next=NULL;
free(temp);
}
else
{
while(traverse->next!=NULL&&position-1!=0)
{
traverse=traverse->next;
position--;
}
if(traverse==NULL || position-1!=0)
{
printf(".............Invalid position..........\n");
}
else
{
traverse->prev->next=traverse->next;
if(traverse->next)
traverse->next->prev=traverse->prev;
}
}
}
struct Student *CreateStudentList(const int no_of_students)
{
struct Student *head=NULL;
int i;
int rno;
char name[20];
for(i=0;i<no_of_students;i++)
{
printf("Enter roll number and name:");
scanf("%d%s",&rno,name);
head=Insert(head,i+1,rno,name);
}
return head;
}
void SimulateDoublyLinkedList()
{
struct Student *cdscpp2013=NULL;
int no_of_students;
int choice,rno,position;
char name[20];
while(choice!=5)
{
if(NULL==cdscpp2013)
{
printf("Enter number of students:");
scanf("%d",&no_of_students);
cdscpp2013=CreateStudentList(no_of_students);
}
else
{
printf("\nMenu Operations\nPress 1 for Insert\nPress 2 for Delete\nPress 3 for DeleteAll\nPress 4 for Display\nPress 5 for Exit\nEnter your choice:");
scanf("%d",&choice);
switch(choice)
{
case 1:
printf("Enter roll number and name to ininsert:");
scanf("%d%s",&rno,name);
printf("Enter position to insert:");
scanf("%d",&position);
cdscpp2013=Insert(cdscpp2013,position,rno,name);
break;
case 2:
printf("Enter position to delete:");
scanf("%d",&position);
Delete(cdscpp2013,position);
break;
case 3:
DeleteAll(cdscpp2013);
break;
case 4:
Display(cdscpp2013);
break;
case 5:
exit(1);
default:
printf("Invalid choice....Please Enter proper option.....");
}
}
}
}
int main()
{
SimulateDoublyLinkedList();
}
When you remove the first element of a list, the caller must update its reference to the list. So your Delete function must return the pointer to the first element of the resulting list.
In this kind of operation I also find useful to use pointers to pointers... this would simplify a lot your code.
try this for delete this should work -
as temp = head , the temp->next =null will make the whole list disappear
//just removed temp->next = null;
if(position==1) {
if(head->next!=NULL)
head=head->next;
head->prev=NULL;
free(temp);
}
Edited --
make delete function to return the head pointer and in the switch case use this
cdscpp2013=Delete(cdscpp2013,position);
instead of this
Delete(cdscpp2013,position);
then change the same for deleteall function - it should work :)