Save structs in a file - c

I'm doing a program to save a list of contacts in a file whit structs. I've tried a lot of things but when I try go read the file to the program, it doesn't read anything.
This is my program without opening files and saving to files:
#include <stdio.h>
#include <stdlib.h>
struct agenda {
int idContacte;
char name[50];
struct agenda *nextContacte;
};
struct agenda *pAgenda;
struct agenda *pFirst = NULL;
struct agenda *pIndex;
void insert();
void show();
int main()
{
//Menu
int opc;
while(1){
printf("1.Insert Contact.\n");
printf("2.Show Contacts.\n");
printf("3.Exit\n");
scanf("%d", &opc);
switch(opc){
case 1:
insert();
break;
case 2:
show();
break;
case 3:
return 0;
}
}
}
void insert(){
pAgenda = (struct agenda *)malloc(sizeof(struct agenda));
printf("Insert ID: ");
scanf("%d", &pAgenda->idContacte);
printf("Insert the name: ");
scanf("%s", pAgenda->name);
printf("\n");
if (pFirst==NULL || pAgenda->idContacte < pFirst->idContacte)
{
pAgenda->nextContacte=pFirst;
pFirst=pAgenda;
}
else if (pAgenda->idContacte > pFirst->idContacte){
pIndex=pFirst;
while(pIndex->nextContacte && pIndex->nextContacte->idContacte < pAgenda->idContacte)
{
pIndex = pIndex->nextContacte;
}
pAgenda->nextContacte = pIndex->nextContacte;
pIndex->nextContacte = pAgenda;
}
}
void show(){
pIndex = pFirst;
while(pIndex && pIndex->idContacte <= 100) {
printf("\nID: %d", pIndex->idContacte);
printf("\nNAME: %s", pIndex->name);
printf("\n\n");
pIndex = pIndex->nextContacte;
}
}
Can you help me how can I get contact at start of the program from a file, and then when insert a contact, rewrite the file and insert all the contacts again in the file?

When you end your program you should do the following
int save_list(struct agenda *head) {
FILE *save = fopen("file.name", "wb");
if(!save) return -1;
while(head) {
fwrite(head, sizeof *head - sizeof head, 1, save);
head = head->nextContacte;
}
fclose(save);
/* Somebody would free list memory after this function execution */
return 0;
}
At the start of your program you should do the following
struct agenda *restore_list() {
FILE *restore= fopen("file.name", "rb");
struct agenda *head = NULL;
struct agenda *cur = head;
struct agenda temp;
if(!restore) return head;
while( fwrite(&temp, sizeof temp - sizeof head, 1, save) == 1) {
struct agenda *node = malloc( sizeof(struct agenda) );
if(NULL == node) {
/* Handle out of memory error here, free list */
return NULL;
}
*node = temp;
node->nextContacte = NULL;
if(head) {
cur->nextContacte = node;
cur = node;
} else {
/* First node */
head = cur = node;
}
}
fclose(restore);
return head;
}

Related

Segmentation fault error in Linked-List program

I'm facing the segmentation fault error in the following dynamic linked list implementation; GDB shows the issue is on the node = node->next line in the "l_print" function of the linked-list ("LIST_CL.H" file). Anyone can help? I even tried "drawing debug" on paper but still I'm not getting the issue here.
Note: I report the whole code for both the insert and the print, in case it's useful. Therefore LIST.C file include the "switch case 6" to insert the element ("l_add" function in "LIST_CL.H" file) and the "switch case 1" to print the list ("l_print" function in "LIST_CL.H" file)
Note: The issue only happen when the list has one or more items. There's no errors when the list is empty ("list_cl" struct has NULL for both head and tail nodes)
LIST.C:
#include <stdio.h>
#include <string.h> //for strcpy
#include "cl_list.h"
#include "list_cl.h"
#define STRING_SIZE 25
int main(){
list_cl class = L_EMPTYLIST_CL;
puts("Select command:");
puts("0. Exit.");
puts("1. Insert node.");
puts("6. Print all nodes in the linked list.");
int k = 0;
scanf("%d", &k);
while(k != 0){
switch(k){
case 1:
char cf[17] = "";
char first_name[STRING_SIZE] = "";
char last_name[STRING_SIZE] = "";
getchar();
puts("Insert name:");
fgets(first_name, sizeof(first_name), stdin);
puts("Insert surname:");
fgets(last_name, sizeof(last_name), stdin);
puts("Insert fiscal code:");
fgets(cf, sizeof(cf), stdin);
client cliente;
strcpy(cliente.cf, cf);
cliente.first_name = first_name;
cliente.last_name = last_name;
class = l_add_cl(class, cliente);
puts("Node inserted.");
break;
case 6:
l_print(class);
break;
default:
break;
}
scanf("%d", &k);
}
}
LIST_CL.H:
list_cl l_add_cl(list_cl l, client p){
l_node node;
node.id = 1;
node.person = p;
node.next = NULL;
if(l.head == NULL){
//List is empty
l.head = &node;
l.tail = &node;
} else {
l.tail -> next = &node;
l.tail = &node;
}
return l;
}
void l_print(list_cl l){
l_node *node = NULL;
node = l.head;
while(node != NULL){
//client *cliente = &node->person;
//printf("ID Elemento: %d | Name: %s Surname: %s Fiscal Code: %s", node->id, cliente->first_name, cliente->last_name, cliente->cf);
node = node->next; // SEGMENTATION FAULT ERROR HERE!
}
}
CL_LIST.H:
#include "client.h"
typedef struct _node {
unsigned int id;
client person;
struct _node *next;
} l_node;
typedef struct {
l_node *head;
l_node *tail;
} list_cl;
#define L_EMPTYLIST_CL {NULL,NULL}
CLIENT.H:
typedef struct {
char cf[17];
char *first_name;
char *last_name;
} client;
Fixed code:
LIST.C:
#include <stdio.h>
#include <string.h> //for strcpy
#include "cl_list.h"
#include "list_cl.h"
#define STRING_SIZE 25
int main(){
list_cl class = L_EMPTYLIST_CL;
puts("Seleziona un comando:");
puts("0. Exit.");
puts("1. Insert one node.");
puts("6. Print all nodes.");
int k = 0;
scanf("%d", &k);
while(k != 0){
switch(k){
case 1:
char cf[17] = "";
//char first_name[STRING_SIZE] = ""; THIS CAUSE DATA INCONSISTENCY
//char last_name[STRING_SIZE] = ""; THIS CAUSE DATA INCONSISTENCY
char *first_name = malloc(sizeof(char)*STRING_SIZE);
char *last_name = malloc(sizeof(char)*STRING_SIZE);
getchar();
puts("Insert name:");
//fgets(first_name, sizeof(first_name), stdin); ISSUE WITH SIZE OF FIRST_NAME
fgets(first_name, sizeof(char)*STRING_SIZE, stdin);
puts("Insert surname:");
//fgets(last_name, sizeof(last_name), stdin); ISSUE WITH SIZE OF LAST_NAME
fgets(last_name, sizeof(char)*STRING_SIZE, stdin);
puts("IInsert fiscal code:");
fgets(cf, sizeof(cf), stdin);
client *cliente = malloc(sizeof(client));
strcpy(cliente->cf, cf);
cliente->first_name = first_name;
cliente->last_name = last_name;
class = l_add_cl(class, *cliente);
puts("Element inserted.");
break;
case 6:
l_print(class);
break;
default:
break;
}
puts("Select command:");
scanf("%d", &k);
}
}
LIST_CL.H
list_cl l_add_cl(list_cl l, client p){
l_node *node = malloc(sizeof(struct _node));
node->id = 1;
node->person = p;
node->next = NULL;
if(l.head == NULL){
//Empty list
l.head = node;
l.tail = node;
} else {
l.tail -> next = node;
l.tail = node;
l.tail -> next = NULL;
}
return l;
}
void l_print(list_cl l){
l_node *node = NULL;
node = l.head;
while(node != NULL){
client *cliente = &node->person;
printf("ID Element: %d | Name: %s Surname: %s Fiscal code: %s", node->id, cliente->first_name, cliente->last_name, cliente->cf);
node = node->next;
}
}
CL_LIST.H
#include "client.h"
typedef struct _node {
unsigned int id;
client person;
struct _node *next;
} l_node;
typedef struct {
l_node *head;
l_node *tail;
} list_cl;
#define L_EMPTYLIST_CL {NULL,NULL}
CLIENT.H
typedef struct {
char cf[17];
char *first_name;
char *last_name;
} client;

How to insert multiple data in linked list

This program asks for two data ( a name and an id), and then stores them in a linked list and then it should output all the data one by one.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Test
{
char name[16];
int id;
};
typedef struct Node {
struct Test structure;
struct Node * next;
}TNode;
typedef TNodo* Node;
void NewDatainNode(struct Test p, Node *pp)
{
TNode *temp;
temp = malloc(sizeof(struct Node));
temp->structure = p;
temp->next = NULL;
*pp = temp;
}
void ReadData(struct Test * p)
{
printf("\nName:");
scanf(" %s", p->name);
printf("\nID:");
scanf(" %d", &p->id);
}
void ViewNodes(Node node)
{
while(node != NULL)
{
printf("%s %d\n",node->structure.name, node->structure.id);
node = node->next;
}
}
int Menu()
{
int c;
printf("\n\tM E N U ***\n"
"1 - New\n"
"2 - Print\n"
"0 - Exit\n"
"\n>> ");
scanf(" %d", &c);
return c;
}
int main()
{
int c;
struct Prova test;
struct Node * list = NULL;
do {
c = Menu();
switch (c)
{
case 1: ReadData(&test);
NewDatainNode(test, &list);break;
case 2: ViewNodes(lista); break;
default: c = 0;
}
} while (c != 0);
return 0;
}
The problem is that it outputs only the last data that has been inserted, what should i do to make it output all the data retrieved in function NuovaPrenotazione()?.
UPDATE: Now the function NewDatainNodes() looks like this:
void NewDatainNode(struct Test p, Node *pp)
{
TNode *temp;
temp = malloc(sizeof(struct Node));
temp->structure = p;
temp->next = *pp;
*pp = temp;
}
Thanks to Sandeep for the correction, the function works even without a return value,the problem was temp->structure = NULL.
This question is exactly duplicate copy of a question posted yesterday and marked as duplicate. But, here is your working code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
struct Prova
{
char nome[16];
int id;
};
typedef struct Node {
struct Prova struttura;
struct Node * next;
}TNodo;
typedef TNodo* Nodo;
Nodo NuovaPrenotazione(struct Prova p, Nodo pp)
{
Nodo temp;
temp = (Nodo)malloc(sizeof(struct Node));
temp->struttura = p;
temp->next = pp;
pp = temp;
return pp;
}
void LeggiPrenotazione(struct Prova * p)
{
printf("\nNome Cliente:");
scanf(" %s", p->nome);
printf("\nID:");
scanf(" %d", &p->id);
}
void Visualizza(struct Prova p)
{
printf("%s %d\n", p.nome, p.id);
}
void VisualizzaPrenotazione(Nodo nodo)
{
while(nodo != NULL)
{
Visualizza(nodo->struttura);
nodo = nodo->next;
}
}
int Menu()
{
int scelta;
printf("*** M E N U ***\n"
"1 - New\n"
"2 - Print\n"
"0 - Esci\n"
"Scelta --> ");
scanf(" %d", &scelta);
return scelta;
}
int main()
{
int scelta;
struct Prova test;
Nodo lista = NULL;
do {
scelta = Menu();
switch (scelta)
{
case 1: LeggiPrenotazione(&test);
lista = NuovaPrenotazione(test, lista);
break;
case 2: VisualizzaPrenotazione(lista); break;
default: scelta = 0;
}
} while (scelta != 0);
return 0;
}
Update: Here is the output

Linked list insertion doesn't work as expected

I'm writing a function that places new nodes alphabetically into a linked list structure by sorting them by the name field. Here is my program, intended to test that it can successfully insert a new node into an existing structure:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_NAME_LENGTH 100
#define MAX_JOB_LENGTH 100
struct Employee
{
/* Employee details */
char name[MAX_NAME_LENGTH+1]; /* name string */
char sex; /* sex identifier, either ’M’ or ’F’ */
int age; /* age */
char job[MAX_JOB_LENGTH+1]; /* job string */
/* pointers to previous and next employee structures in the linked list
(for if you use a linked list instead of an array) */
struct Employee *prev, *next;
};
void place_alpha(struct Employee *new, struct Employee **root);
int main(){
struct Employee *a;
struct Employee *c;
struct Employee *b;
a = malloc(sizeof(struct Employee));
c = malloc(sizeof(struct Employee));
b = malloc(sizeof(struct Employee));
strcpy(a->name, "A");
a->sex = 'F';
a->age = 42;
strcpy(a->job, "Optician");
a->prev = NULL;
a->next = c;
strcpy(c->name, "C");
c->sex = 'F';
c->age = 22;
strcpy(c->job, "Nurse");
c->prev = a;
c->next = NULL;
strcpy(b->name, "B");
b->sex = 'M';
b->age = 34;
strcpy(b->job, "Rockstar");
b->prev = NULL;
b->next = NULL;
place_alpha(b, &a);
if(a->prev == NULL)
{
printf("a->prev is correct\n");
}else{
printf("a->prev is INCORRECT\n");
}
if(a->next == b)
{
printf("a->next is correct\n");
}else{
printf("a->next is INCORRECT");
}
if(b->prev == a)
{
printf("b->prev is correct\n");
}else{
printf("b->prev is INCORRECT\n");
}
if(b->next == c)
{
printf("b->next is correct\n");
}else{
printf("b->next is INCORRECT\n");
}
if(c->prev == b)
{
printf("c->prev is correct\n");
}else{
printf("c->prev is INCORRECT\n");
}
if(c->next == NULL)
{
printf("c->next is correct\n");
}else{
printf("c->next is INCORRECT\n");
}
}
void place_alpha(struct Employee *new, struct Employee **root) //Places a new node new into the database structure whose root is root.
{
if(*root==NULL) //If there is no database yet.
{
*root = new;
(*root)->prev = NULL;
(*root)->next = NULL;
}
else
{
if(strcmp(new->name, (*root)->name)<=0) // if the new node comes before root alphabetically
{
new->next = *root;
new->prev = (*root)->prev;
if((*root)->prev != NULL)
{
(*root)->prev->next = new;
}
(*root)->prev = new;
*root = new;
return;
}
else if((*root)->next == NULL) // If the next node is NULL (we've reached the end of the database so new has to go here.
{
new->prev = *root;
new->next = NULL;
(*root)->next = new;
return;
}
else if(strcmp(new->name, (*root)->name)>0) // If the new node comes after root alphabetically
{
place_alpha(new, &(*root)->next);
return;
}
}
}
Sadly, the program is unsuccessful, as showcased by the output:
a->prev is correct
a->next is correct
b->prev is INCORRECT
b->next is correct
c->prev is INCORRECT
c->next is correct
Program ended with exit code: 0
I can't figure out why, as I've clearly set b->next to c and c->prev to b.
This was tricky: there is a subtile bug in your place_alpha() function: you update *root even if it is not the root node of the list. This causes the pointer b to be updated erroneously. place_alpha() should only be called with a pointer to the actual root node.
I modified your code to make it more readable and reliable:
I wrote a function to create a new node
I protected the string copies from overflow using calloc() and strncat(). Read about these functions in the manual.
I use place_alpha() to insert all 3 nodes into the list in the same order you do.
I use newp instead of new to avoid C++ keywords in C code.
Note that place_alpha() must be called with a pointer to the head pointer of the list, if you pass a pointer to an intermediary node, chaining back along the prev links would locate the first node, but if the new employee should be inserted at the head of the list, you would not have the address of the root node to update in the caller's scope. This is the reason many programmers prefer to use a specific structure for the list head.
Here is the updated code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_NAME_LENGTH 100
#define MAX_JOB_LENGTH 100
struct Employee {
/* Employee details */
char name[MAX_NAME_LENGTH + 1]; /* name string */
char sex; /* sex identifier, either 'M' or 'F' */
int age; /* age */
char job[MAX_JOB_LENGTH + 1]; /* job string */
/* pointers to previous and next employee structures in the linked list
(for if you use a linked list instead of an array) */
struct Employee *prev, *next;
};
void place_alpha(struct Employee *new, struct Employee **root);
struct Employee *new_employee(const char *name, char sex, int age, const char *job) {
struct Employee *newp = calloc(1, sizeof(*newp));
if (!newp) {
fprintf(stderr, "cannot allocate employee\n");
exit(1);
}
strncat(newp->name, name, MAX_NAME_LENGTH);
newp->sex = sex;
newp->age = age;
strncat(newp->job, job, MAX_JOB_LENGTH);
newp->next = newp->prev = NULL;
return newp;
}
int main(void) {
struct Employee *list = NULL;
struct Employee *a = new_employee("A", 'F', 42, "Optician");
struct Employee *b = new_employee("B", 'M', 34, "Rockstar");
struct Employee *c = new_employee("C", 'F', 22, "Nurse");
place_alpha(a, &list);
place_alpha(c, &list);
place_alpha(b, &list);
if (a->prev == NULL) {
printf("a->prev is correct\n");
} else {
printf("a->prev is INCORRECT\n");
}
if (a->next == b) {
printf("a->next is correct\n");
} else {
printf("a->next is INCORRECT");
}
if (b->prev == a) {
printf("b->prev is correct\n");
} else {
printf("b->prev is INCORRECT\n");
}
if (b->next == c) {
printf("b->next is correct\n");
} else {
printf("b->next is INCORRECT\n");
}
if (c->prev == b) {
printf("c->prev is correct\n");
} else {
printf("c->prev is INCORRECT\n");
}
if (c->next == NULL) {
printf("c->next is correct\n");
} else {
printf("c->next is INCORRECT\n");
}
return 0;
}
void place_alpha(struct Employee *newp, struct Employee **root) {
// Insert a new node newp into the database structure whose root is root.
struct Employee *ep;
if (*root == NULL) { // if there is no database yet.
newp->next = newp->prev = NULL;
*root = newp;
return;
}
if ((*root)->prev) {
// invalid call, should only pass the root node address
fprintf(stderr, "invalid call: place_alpha must take a pointer to the root node\n");
return;
}
if (strcmp(newp->name, (*root)->name) <= 0) {
// if the new node comes before root alphabetically
newp->next = *root;
newp->prev = NULL;
newp->next->prev = newp;
*root = newp;
return;
}
for (ep = *root;; ep = ep->next) {
if (ep->next == NULL) {
// If the next node is NULL, we've reached the end of the list
// so newp has to go here.
newp->prev = ep;
newp->next = NULL;
newp->prev->next = newp;
return;
}
if (strcmp(newp->name, ep->next->name) <= 0) {
// The new node comes between ep and ep->next alphabetically
newp->prev = ep;
newp->next = ep->next;
newp->prev->next = newp->next->prev = newp;
return;
}
}
}
EDIT: place_alpha was a bit redundant, so I cleaned it and got a much simpler version:
void place_alpha(struct Employee *newp, struct Employee **root) {
//Places a new node newp into the database structure whose root is root.
struct Employee **link = root;
struct Employee *last = NULL;
while (*link && strcmp(newp->name, (*link)->name) > 0) {
last = *link;
link = &last->next;
}
newp->prev = last;
newp->next = *link;
if (newp->next) {
newp->next->prev = newp;
}
*link = newp;
}

Pointers and binary search tree

I am working on a program that uses a binary search tree (as an exercise).
My problem is that when I try to add a customer(in the middle of my code lines 65-69) I get an error that BS_node is undeclared, though I insert struct BST_node *root in this function..
Part of my code is below, just for the readers to read it easier, if requested I can upload the full code ! Thanks!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_STRING 50
void flush();
struct customer {
char *name;
char *address;
char *email;
};
struct double_linked_list {
struct customer *data;
struct double_linked_list *previous;
struct double_linked_list *next;
};
struct double_linked_list *customers_head=0;
struct BST_node {
struct double_linked_list *data;
struct BST_node *left;
struct BST_node *right;
};
struct BST_node *BST_email_root = 0;
struct BST_node *BST_find_customer(struct BST_node *root, char *email) {
if (root==NULL)
return NULL;
if (strcmp(email,root->data->data->email)==0)
return root;
else
{
if (strcmp(email,root->data->data->email)==-1)
return BST_find_customer(root->left,email);
else
return BST_find_customer(root->right,email);
}
}
void find_customer() {
char email[MAX_STRING];
struct double_linked_list *l;
struct BST_node *b;
printf("Give the email of the customer (up to %d characters) : ", MAX_STRING-1);
gets(email);
b = BST_find_customer(BST_email_root, email);
if (b==0)
printf("There is no customer with this email.\n");
else
{
l = b->data;
printf("Customer found! \n");
printf("Name : %s\n", l->data->name);
printf("Address : %s\n", l->data->address);
printf("Email : %s\n", l->data->email);
}
}
struct BST_node *new_BST_node(struct BST_node *root, struct double_linked_list *l)
{
if (root==NULL);
{
root = (BST_node *) malloc (sizeof(BST_node ));
if (root==NULL)
{
printf("Out of Memory!");
exit(1);
}
root->data=l;
root->left=NULL;
root->right=NULL;
}
if (strcmp(l->data->email,root->data->data->email)==-1)
root->left =new_BST_node(root->left,l);
else root->right =new_BST_node(root->right,l);
return root;
};
struct double_linked_list *new_customer()
{
char name[MAX_STRING], address[MAX_STRING], email[MAX_STRING];
struct BST_node *b;
struct double_linked_list *l;
struct customer *c;
printf("\nADDING NEW CUSTOMER\n=\n\n");
printf("Give name (up to %d characters): ", MAX_STRING-1);
gets(name);
printf("Give address (up to %d characters): ", MAX_STRING - 1);
gets(address);
printf("Give email (up to %d characters): ", MAX_STRING - 1);
gets(email);
b = BST_find_customer(BST_email_root, email);
if (b)
{
printf("Duplicate email. Customer aborted.\n");
return 0;
}
c = (struct customer *) malloc(sizeof(struct customer));
if (c == 0)
{
printf("Not enough memory.\n");
return 0;
}
c->name = strdup(name); // check for memory allocation problem
if (c->name == 0) return 0;
c->address = strdup(address); // check for memory allocation problem
if (c->address == 0) return 0;
c->email = strdup(email); // check for memory allocation problem
if (c->email == 0) return 0;
l = (struct double_linked_list*) malloc(sizeof(struct double_linked_list));
if (l == 0)
{
printf("Not enough memory.\n");
free(c->name);
free(c->address);
free(c->email);
free(c);
return 0;
}
l->data = c;
l->previous = 0;
l->next = customers_head;
if (customers_head)
customers_head->previous = l;
customers_head = l;
BST_email_root = new_BST_node(BST_email_root, l);
return l;
}
void displaymenu() {
printf("\n\n");
printf("1. New customer\n");
printf("2. Find customer using email\n");
printf("0. Exit\n\n");
printf("Give a choice (0-6) : ");
}
void flush()
{
char ch;
while ((ch = getchar()) != '\n' && ch != EOF);
}
int main() {
int choice;
do {
displaymenu();
scanf("%d", &choice);
flush();
switch (choice) {
case 1:
new_customer();
break;
case 2:
find_customer();
break;
} while (choice != 0);
return 0;
}
On the line 69, you have to specify struct BST_node instead of BST_node:
root = (struct BST_node *) malloc (sizeof(struct BST_node ));
As for the rest of the code: read the manual for gets, it's clearly a function one should not use, I'd advise replacing it with fgets. There's also a little closing bracket missing in your final switch (line 178).

Printing and Deleting queue in C

I'm trying to write a program that enqueue, dequeue, delete a chosen number and print the list. I have problems with the dequeue that i think is because of the menu part when you write a number, I've tried to fix it but the it removes the last number and not the first. The print shows the wrong number and when I tried to solve that problem I got the same problem as I had in dequeue. It's sometinhg wrong in delete but i cant figure it out.
I appreciate all the help i can get
edit:
I've changed it a lot and now everything else works except delete. I want delete to find the number i enter and delete it.
queue.c
#include <stdio.h>
#include <stdlib.h>
#include<conio.h>
struct node
{
int info;
struct node *ptr;
int next;
}*first, *last, *temp, *first1;
void enq(int data);
void deq();
void empty();
void display();
void create();
void delete_queue();
int count = 0;
void main()
{
int no, ch;
printf("\n 1 - Enqueue");
printf("\n 2 - Dequeue");
printf("\n 3 - Delete");
printf("\n 4 - Display");
printf("\n 5 - Exit");
create();
while (1)
{
printf("\n Enter choice : ");
scanf_s("%d", &ch);
switch (ch)
{
case 1:
printf("Enter data : ");
scanf_s("%d", &no);
enq(no);
break;
case 2:
deq();
break;
case 3:
printf("Enter data : ");
scanf_s("%d", &no);
delete_queue(no);
case 4:
display();
break;
case 5:
exit(0);
default:
printf("Wrong choice, Please enter correct choice ");
break;
}
}
}
void create()
{
first = last = NULL;
}
void enq(int data)
{
if (last == NULL)
{
last = (struct node *)malloc(1 * sizeof(struct node));
last->ptr = NULL;
last->info = data;
first = last;
}
else
{
temp = (struct node *)malloc(1 * sizeof(struct node));
last->ptr = temp;
temp->info = data;
temp->ptr = NULL;
last = temp;
}
count++;
}
void display()
{
first1 = first;
if ((first1 == NULL) && (last == NULL))
{
printf("Queue is empty");
return;
}
while (first1 != last)
{
printf("%d ", first1->info);
first1 = first1->ptr;
}
if (first1 == last)
printf("%d", first1->info);
}
void deq()
{
first1 = first;
if (first1 == NULL)
{
printf("\n Error: Trying to display elements from empty queue");
return;
}
else
if (first1->ptr != NULL)
{
first1 = first1->ptr;
printf("\n Dequed value : %d", first->info);
free(first);
first = first1;
}
else
{
printf("\n Dequed value : %d", first->info);
free(first);
first = NULL;
last = NULL;
}
count--;
}
void delete_queue()
{
int retval = -1;
if (first)
{
struct node *temp = first;
first = first->next;
if (!first) { last = first; }
retval = temp->next;
free(temp);
}
return retval;
}
void empty()
{
if ((first == NULL) && (last == NULL))
printf("\n Queue empty");
else
printf("Queue not empty");
}
Let me start with a few points of advice about design and style:
I do not recommend this:
typedef struct node {
int data;
struct node *next;
} node;
you are typedefing struct node to node. while it is not illegal, it is confusing. I would recommend
typedef struct _node {
int data;
struct _node *next;
} node;
Additionally, I do not recommend use of global variable with static storage class to keep track of your queue, instead you should create a queue in your main. Use global variables only when you have compelling reasons to do so.
Do remember that when you get rid of your global variable, you will need to rewrite your enqueue dequeue delete etc... functions to take in a queue_c * as parameter (because it wont have access to queueref any more)
Now for the reason that your code is not working properly and #Weather Vane alluded to:
you have a big problem in your delete function.
int delete(int data)
{
int result = 0;
node *curr_ptr; //pointer just created and not initialized
node *prev_ptr; //not initialized
node *temp_ptr; //not initialized
while (curr_ptr != NULL)
//curr_ptr was just created, where is it pointing? fatal error here
{
//inside this block lets imagine curr_ptr is pointing to a valid
//node in the global queue
if (curr_ptr->data == data)
{
result = 1;
if (curr_ptr->next != NULL)
{
temp_ptr = curr_ptr;
//both pointers point to the same thing
destroy_node(temp_ptr);
//now you just destroyed both nodes
prev_ptr->next = curr_ptr->next;
//the first time this block runs prev_ptr is uninitialized
//so prev_ptr->next will most likely seg fault
//this happens for example if you call this function
//for the first time with a long queue
}
else
{
temp_ptr = curr_ptr;
queueref.last = prev_ptr;
prev_ptr->next = NULL;
destroy_node(temp_ptr);
//again you are destroying both curr_ptr and temp_ptr
}
}
curr_ptr = curr_ptr->next;
prev_ptr = prev_ptr->next;
return result;
}
}
Perhaps it would be better if you think edge cases very carefully and rethink some of the logic from scratch. (test edge cases as you go)

Resources