C QueueLinkedList string variable not working - c

#include<stdlib.h>
struct customer
{
int phoneNum;
char *name;
struct customer *nxt;
};
struct customer *initialNode(int i, char *n);
int isEmpty(struct customer *head, struct customer *tail);
void enqueue(int phNum1, char *cName1, struct customer *tail);
void dequeue(struct customer *head, struct customer *tail);
void display(struct customer *head, struct customer *tail);
int main()
{
int phNum;
char *cName;
int choice;
struct customer *head;
struct customer *tail;
head = initialNode(0, NULL);
tail = initialNode(0, NULL);
head->nxt = tail;
tail->nxt = head;
while (choice !=4)
{
printf("\nEnter your option:");
printf("\n1. Enqueue new customer. \n2. Dequeue customer. \n3. Display customer in queue. \n4. Exit. \nOption: ");
scanf("%d", &choice);
switch(choice)
{
case 1:
{
printf("\nEnter customer phone number: ");
scanf("%d", &phNum);
printf("\nEnter customer name: ");
scanf("%s", cName);
enqueue(phNum, cName, tail);
break;
}
case 2:
{
dequeue(head, tail);
break;
}
case 3:
{
display(head, tail);
break;
}
default:
{
if (choice < 1 || choice > 4)
printf("\nInvalid option!\n");
break;
}
}
}
}
struct customer *initialNode(int i, char *n)
{
struct customer *newCustomer = malloc(sizeof(struct customer));
newCustomer->phoneNum = i;
newCustomer->name = n;
newCustomer->nxt = NULL;
return newCustomer;
}
int isEmpty ( struct customer *head, struct customer *tail)
{
if (head->nxt == tail)
return 1;
else
return 0; //cannot is full because it is not array, have no size limitation
}
void enqueue(int phNum1, char *cName1, struct customer *tail)
{
struct customer *nC = malloc(sizeof(struct customer));
nC = initialNode(phNum1, cName1);
nC->nxt = tail;
tail->nxt->nxt = nC;
tail->nxt = nC;
printf("\nSuccessfully enqueue a customer!\n");
}
void dequeue(struct customer *head, struct customer *tail)
{
struct customer *removedCustomer = malloc(sizeof(struct customer));
if (isEmpty(head, tail) == 1)
{
printf("\nThe queue is empty!\n");
}
else
{
removedCustomer = head->nxt;
printf("\nFirst customer is removed.\n");
head->nxt = head->nxt->nxt;
}
}
void display(struct customer *head, struct customer *tail)
{
struct customer *tempH = malloc(sizeof(struct customer));
tempH = head;
tempH = tempH->nxt;
if (isEmpty(head, tail) == 1)
{
printf("\nThe queue is empty!\n");
}
else
{
printf("\n===Current customer list===");
while (tempH != tail)
{
printf("\n\tCustomer phone number : %d", tempH->phoneNum);
printf("\n\tCustomer name: %s\n", tempH->name);
tempH = tempH->nxt;
}
}
}
The code is suppose to make queue of a list of customer that user input their phone number and name, code is working well but when i input a new customer, the customer before's name all somehow become the latest customer's name..
How do i solve this? Do i declare a 2D string array to collect different set of customer's name?

I see the below issues with the code.
The head and tail should be initialized to NULL. This signifies an empty list.
In the initialnode function you are directly assigning the scanned pointer as newCustomer->name = n. This is wrong. As you have declared the struct as having a character pointer, you need to also allocate space for each string separately.
The enqueue and dequeue functions can change the value of the head and tail pointers in the main function. You can change the function declarations to pass a double pointer for this.
You also need to free the struct on dequeue. This is strictly not necessary in a small program but is a good practice anyway to avoid memory leaks in larger programs.
In the display function you are having an unnessary malloc which needs to be removed. This function does not need to allocate memory.
The variable choice in main is not initailized.
Please see the code below
#include<stdlib.h>
#include <stdio.h>
#include <string.h>
struct customer
{
int phoneNum;
char *name;
struct customer *nxt;
};
struct customer *initialNode(int i, char *n);
int isEmpty(struct customer *head, struct customer *tail);
void enqueue(int phNum1, char *cName1, struct customer **head, struct customer **tail);
void dequeue(struct customer **head, struct customer **tail);
void display(struct customer *head, struct customer *tail);
int main(void)
{
int phNum;
char cName[51]; // max name length supported
int choice = 0;
struct customer *head;
struct customer *tail;
head = NULL;
tail = NULL;
while (choice !=4)
{
printf("\nEnter your option:");
printf("\n1. Enqueue new customer. \n2. Dequeue customer. \n3. Display customer in queue. \n4. Exit. \nOption: ");
scanf("%d", &choice);
switch(choice)
{
case 1:
{
printf("\nEnter customer phone number: ");
scanf("%d", &phNum);
printf("\nEnter customer name: ");
scanf("%s", cName);
enqueue(phNum, cName, &head, &tail);
break;
}
case 2:
{
dequeue(&head, &tail);
break;
}
case 3:
{
display(head, tail);
break;
}
default:
{
if (choice < 1 || choice > 4)
printf("\nInvalid option!\n");
break;
}
}
}
return 0;
}
struct customer *initialNode(int i, char *n)
{
int len;
struct customer *newCustomer = malloc(sizeof(struct customer));
newCustomer->phoneNum = i;
len = strlen(n);
newCustomer->name = malloc(len +1);
strcpy(newCustomer->name, n);
newCustomer->nxt = NULL;
return newCustomer;
}
int isEmpty ( struct customer *head, struct customer *tail)
{
if ((head == NULL) && (tail == NULL))
return 1;
else
return 0; //cannot is full because it is not array, have no size limitation
}
void enqueue(int phNum1, char *cName1, struct customer **head, struct customer **tail)
{
struct customer *nC = malloc(sizeof(struct customer));
nC = initialNode(phNum1, cName1);
if (isEmpty(*head,*tail))
{
*head = nC;
*tail = nC;
}
else if (*head == *tail) // single element
{
(*head)->nxt = nC;
*tail = nC;
}
else
{
(*tail)->nxt = nC;
*tail = nC;
}
printf("\nSuccessfully enqueue a customer!\n");
}
void dequeue(struct customer **head, struct customer **tail)
{
struct customer *removedCustomer = malloc(sizeof(struct customer));
if (isEmpty(*head, *tail) == 1)
{
printf("\nThe queue is empty!\n");
}
else if (*head == *tail) // single element
{
removedCustomer = *head;
free(removedCustomer->name);
free(removedCustomer);
*head = NULL;
*tail = NULL;
}
else
{
removedCustomer = *head;
*head = (*head)->nxt;
free(removedCustomer->name);
free(removedCustomer);
printf("\nFirst customer is removed.\n");
}
}
void display(struct customer *head, struct customer *tail)
{
struct customer *tempH;
tempH = head;
if (isEmpty(head, tail) == 1)
{
printf("\nThe queue is empty!\n");
}
else
{
printf("\n===Current customer list===");
while (tempH != NULL)
{
printf("\n\tCustomer phone number : %d", tempH->phoneNum);
printf("\n\tCustomer name: %s\n", tempH->name);
tempH = tempH->nxt;
}
}
}

Related

Creating a C string array, when reading from file

im doing a project, where i need to manage a queue of sorts, specifically cars in a car wash. I've found some code online, that allows you to add to queue and manage it, with integer inputs. Is there a way for me to re-write this code, so that it accepts inputs as c strings instead of integers?
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
};
struct node *front = NULL;
struct node *rear = NULL;
void display();
void enqueue(int);
void dequeue();
int main()
{
int n, ch;
do
{
printf("\n\nQueue Menu\n1. Add \n2. Remove\n3. Display\n0. Exit");
printf("\nEnter Choice 0-3? : ");
scanf("%d", &ch);
switch (ch)
{
case 1:
printf("\nEnter number ");
scanf("%d", &n);
enqueue(n);
break;
case 2:
dequeue();
break;
case 3:
display();
break;
}
}while (ch != 0);
}
void enqueue(int item)
{
struct node *nptr = malloc(sizeof(struct node));
nptr->data = item;
nptr->next = NULL;
if (rear == NULL)
{
front = nptr;
rear = nptr;
}
else
{
rear->next = nptr;
rear = rear->next;
}
}
void display()
{
struct node *temp;
temp = front;
printf("\n");
while (temp != NULL)
{
printf("%d\t", temp->data);
temp = temp->next;
}
}
void dequeue()
{
if (front == NULL)
{
printf("\n\nqueue is empty \n");
}
else
{
struct node *temp;
temp = front;
front = front->next;
printf("\n\n%d deleted", temp->data);
free(temp);
}
}
Where the desired input would be one of these strings;
AV96888 VW alm
KD65656 Audi luksus
AX21878 Ford alm
CN32323 VW alm
NB21214 Ford luksus
UM21878 Ford alm
AV54361 Tesla luksus
Yes, the data is stored in the node:
struct node
{
int data;
struct node *next;
};
So you just need to change the int data; to a string.
Are there a reason you are doing this in C and not c++ ? There, string management is easier.
Here is the answer, you just convert the data to char * and use strdup to store the pointer
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
struct node
{
char *data;
struct node *next;
};
struct node *front = NULL;
struct node *rear = NULL;
void enqueue(char *item)
{
struct node *nptr = malloc(sizeof(struct node));
nptr->data = strdup(item);
nptr->next = NULL;
if (rear == NULL)
{
front = nptr;
rear = nptr;
}
else
{
rear->next = nptr;
rear = rear->next;
}
}
void display()
{
struct node *temp;
temp = front;
printf("\n");
while (temp != NULL)
{
printf("%s\t", temp->data);
temp = temp->next;
}
}
void dequeue()
{
if (front == NULL)
{
printf("\n\nqueue is empty \n");
}
else
{
struct node *temp;
temp = front;
front = front->next;
printf("\n\n%d deleted", temp->data);
free(temp->data);
free(temp);
}
}
int main()
{
int ch;
char n[256];
do {
printf("\n\nQueue Menu\n1. Add \n2. Remove\n3. Display\n0. Exit");
printf("\nEnter Choice 0-3? : ");
scanf("%d", &ch);
switch (ch)
{
case 1:
printf("\nEnter a name: ");
scanf("%s", n);
enqueue(n);
break;
case 2:
dequeue();
break;
case 3:
display();
break;
}
}while (ch != 0);
}

Inputting Values in the members of structure through linked list

I am working in C. Here, I have a structure Node with data members passengers and station. I have a function which inputs the passenger number and stop Name from the user.
struct Node
{
int stopNo;
int passenger;
char station[50];
struct node* next;
};
I have a function which takes the input as the name of station and passengers no and automatically increase the stopNo by 1.
I am trying to Use a linked list to store the stations.
#include<stdio.h>
#include<stdlib.h>
struct Node
{
int stopNo;
int passenger;
char station[50];
struct node* next;
};
void takeInput(struct Node* head)
{
head->stopNo = head->stopNo +1;
printf("Station Name");
scanf(" %[^\n]s",head->station);
printf("New Passengers ");
scanf("%d",&head->passenger);
}
void printStops(struct Node* head)
{
for(int i=0;i<=head->stopNo;i++)
{
printf("Stop %d. %s with %d passenger",head->stopNo,head->station,head->passenger);
}
}
int main()
{ int n;
struct Node* head = NULL;
struct Node* second = NULL;
//Memory Allocation into heap
head = (struct Node*)malloc(sizeof(struct Node));
second = (struct Node*)malloc(sizeof(struct Node));
while(1){
//Menu
printf("1.Log Stops\n");
printf("2.Print Stop");
printf("3.Exit");
scanf("%d",&n);
switch(n){
case 1:
takeInput(struct Node*);
break;
case 2:
printStops(struct Node*);
break;
case 3:
exit(0);
default:
printf("Enter the numbers from 1 to 2");
}
}
}
I am confused what to pass as an argument through the function.
You are mis-using the linked list concept.
The principle is to dynamically add new nodes at the beginning (simpler) or at the end (slightly more complex). Here, as you already have a function dedicated to feeding the list, you could just allocate the nodes there. A possible way is to pass the address of the current head, and let the function change it. But you have to define a sentinel value to tell the function that you do not want to input more nodes.
In the following code "STOP" is that sentinel:
void takeInput(struct Node **head)
{
int stopNo = 0;
for (;;) {
struct Node *node = malloc(sizeof (*node));
node->stopNo = stopNo++;
node->next = *head;
printf("Station Name");
scanf(" %[^\n]",node->station);
if (strcmp(node->station, "STOP") == 0) { // no more station
free(node);
break;
}
printf("New Passengers ");
scanf("%d",&node->passenger);
*head = node;
}
}
That way, you can iterate the list to print its content:
void printStops(struct Node* head)
{
while (head != NULL)
{
printf("Stop %d. %s with %d passenger\n",head->stopNo,head->station,head->passenger);
head = head->next;
}
}
Finally, you main would become:
int main()
{ int n;
struct Node* head = NULL;
while(1){
//Menu
printf("1.Log Stops\n");
printf("2.Print Stop\n");
printf("3.Exit\n");
scanf("%d",&n);
switch(n){
case 1:
takeInput(&head);
break;
...

Weird string value when I return a string value from a node when I dequeue a linked list implementation

The program is not complete. I can add enqueue nodes, display the list of nodes, and find the top of the node, etc... But when I try to dequeue and return a node from the dequeue function the customer's name gets jumbled up. This is a queue implementation in linked list. The application is similar to an order system from a fast-food chain.
Also, I was expected to have this operation in my program:
"INIT(): creates and returns an empty queue."
Did I do it right?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXLENGTH 20
struct Node{
char name[MAXLENGTH];
char order[MAXLENGTH];
struct Node* link;
};
struct Node* Init();
int Empty(struct Node*, struct Node*);
struct Node* Front(struct Node*);
void AskOrder(struct Node**, struct Node**);
void EnQueue(char*, char* , struct Node** , struct Node** );
struct Node* DeQueue(struct Node**, struct Node** );
void display(struct Node* );
int main()
{
struct Node* front = NULL;
struct Node* rear = NULL;
int ch = -1;
struct Node* printme = NULL;
while(ch!=0)
{
printf("ORDER LIST:");
if (Empty(front, rear) != 1)
display(front);
printf("\n\nJohn's Store Menu:\n"
"\n [1] Fall in line"
"\n [2] Serve order"
"\n [3] Next order"
"\n [4] Closing time"
"\n [0] Exit\n"
"\nEnter choice: ");
scanf("%d", &ch);
switch(ch)
{
case 1:
AskOrder(&front, &rear);
break;
case 2:
if(Empty(front, rear) != 1)
{
printme = DeQueue(&front, &rear);
printf("\nNow serving [%s] to customer [%s].\n", printme->order, printme->name);
}else
printf("The QUEUE is EMPTY. No orders to serve.");
break;
case 3:
if(Empty(front, rear) != 1)
{
printme = Front(front);
printf("\nNext order: [%s] of customer [%s].\n", printme->order, printme->name);
}else
printf("The QUEUE is EMPTY. No orders to serve.\n");
break;
case 4:
if(Empty(front, rear) != 1)
{
}else
printf("The QUEUE is EMPTY. No orders to serve.\n");
break;
case 0:
printf("\nOrder system has been terminated.\n");
return 0;
default:
printf("Invalid choice.\n");
break;
}
system("pause");
system("cls");
}
}
struct Node* Init()
{
struct Node* q = (struct Node*)malloc(sizeof(struct Node));
q->link = NULL;
return q;
}
int Empty(struct Node* fr, struct Node* rr)
{
if(fr == NULL && rr == NULL)
{
return 1;
}else{
return 0;
}
}
struct Node* Front(struct Node* fr)
{
return fr;
}
void AskOrder(struct Node** front, struct Node** rear)
{
char name[MAXLENGTH];
char order[MAXLENGTH];
printf("\nWhat's your name? ");
fflush(stdin);
gets(name);
printf("What's your order? ");
fflush(stdin);
gets(order);
EnQueue(name, order, front, rear);
}
void EnQueue(char* nm, char* ordr, struct Node** fr, struct Node** rr)
{
struct Node* temp = Init();
strcpy(temp->name, nm);
strcpy(temp->order, ordr);
if(Empty(*fr, *rr) == 1)
{
*fr = *rr = temp;
return;
}
(*rr)->link = temp;
*rr = temp;
}
struct Node* DeQueue(struct Node** fr, struct Node** rr)
{
struct Node* printme = *fr;
struct Node* temp = *fr;
if(*fr == *rr){
*fr = *rr = NULL;
}else{
*fr = (*fr)->link;
}
free(temp);
return printme;
}
void display(struct Node* fr){
while(fr != NULL)
{
printf("\n[%s] of customer [%s]", fr->order, fr->name);
fr = fr->link;
}
}

Error while printing the linked list

I created the linked list to store employee id and name.
When I tried to print it, it shows only id not an employee name and i also want to exit the program when the user enter -1 and not asking the name its should simply exit the program and display the id and name i am currently using devC++ for compiling my code
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
struct node
{
int id;
char name[20];
struct node *next;
};
struct node *create()
{
struct node *p, *r, *n;
int s, k;
char name[20];
s = sizeof(struct node);
printf("Linked List\n");
printf("Enter id:");
scanf("%d", &k);
printf("Enter name:");
scanf("%s", name);
p = r = NULL;
while(k!=-1)
{
n = (struct node *)malloc(s);
n->id = k;
n->next = NULL;
if(r == NULL)
r = n;
else
p->next=n;
p=n;
printf("Enter the Id or-1 to stop:");
scanf("%d", &k);
printf("Enter the name ");
scanf("%s", name);
}
return(r);
}
void display(struct node *r)
{
printf("\nId Name \n");
while(r != NULL)
{
printf("\n %d", r->id);
printf("\n %s", r->name);
r = r->next;
}
}
int main()
{
struct node *ptr;
ptr = create();
display(ptr);
}
You actually read in the name variable, but you don't move it in your structure.
That said, you could directly read into the structure you allocate, but the tricky part is taking care of not overflowding your buffer when the user input is too big (more than 19 chars).
This could look like this:
#include<stdio.h>
#include<stdlib.h>
struct node {
int id;
char name[20];
struct node *next;
};
struct node *create(void) {
struct node *p, *r;
printf("Linked List\n");
p = r = NULL;
while (1) {
int id;
printf("Enter the Id or-1 to stop:");
scanf("%d", &id);
if (id == -1)
break; // user asked to leave
struct node *n = malloc(sizeof(*n));
// if (n == NULL) exit(-1); as you prefere...
n->id = id;
printf("Enter the name ");
// careful of buffer overflow here
scanf("%19s%*[^\n]", n->name);
n->next = NULL;
if (r == NULL)
r = n;
else
p->next = n;
p = n;
}
return r;
}
void delete(struct node *r) {
while (r != NULL) {
struct node *n = r;
r = r->next;
free(n);
}
}
void display(const struct node *r) {
printf("\nId Name \n");
while (r != NULL) {
printf("%d %s\n", r->id, r->name);
r = r->next;
}
}
int main(int argc, char **argv) {
struct node *ptr = create();
display(ptr);
delete(ptr);
return 0;
}
As a bonus, I also added the free part so that you don't leak.

printing the nodes in linked list in c

here is a program which inserting 2 names 2 paths and 2 duration s into linked list (struct of linked lists) , printing them and swapping between them when the duration of the first node is 8.
but when the program printing the nodes its prints from all of the nodes the name and the path of the last node
please help me
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Frame
{
char *name;
unsigned int duration;
char *path; // may change to FILE*
}*n3;
typedef struct Frame frame_t;
struct Link
{
frame_t *frame;
struct Link *next;
}*n ;
typedef struct Link link_t;
struct Link* insert(struct Link *n3);
void print(struct Link* head, int flag);
void swap(struct Link **head, int value);
#define MAX_PATH_SIZE (256)
#define MAX_NAME_SIZE (50)
int main()
{
struct Link* head = NULL;
int flag = 0;
int num = 0;
char namearray[MAX_NAME_SIZE] = { 0 };
char patharray[MAX_PATH_SIZE] = { 0 };
printf("1\n");
printf("\n");
for (int i = 0; i < 2; i++)
{
printf("Enter a number you want to insert - ");
scanf("%d", &num);
printf("\nEnter the name - ");
scanf("%s", &namearray);
printf("\nEnter the path - ");
scanf("%s", &patharray);
printf("\n");
head = insert(head,num,namearray,patharray);
}
print(head, flag);
swap(&head, 8);
printf("1\n");
system("pause");
return 0;
}
struct Link *insert(struct Link *p, int n, char namearray[MAX_NAME_SIZE], char patharray[MAX_PATH_SIZE]) //insert func
{
struct node *temp;
if (p == NULL) //if the node is empty
{
p = (struct Link *)malloc(sizeof(struct Link)); //gives memory to the node
p->frame = (struct Frame *)malloc(sizeof(struct Frame));
if (p == NULL)
{
printf("Error\n");
}
else
{
printf("The number added to the end of the list\n");
}
p->frame->duration = n; //its runing untill the node item is NULL
p->frame->name = namearray;
p->frame->path = patharray;
p->next = NULL;
}
else
{
p->next = insert(p->next, n , namearray , patharray);/* the while loop replaced by
recursive call */
}
return (p);
}
void print(struct Link* head , int flag)//print func
{
if (head == NULL && flag == 0) //if the node is empty
{
printf("The list is empty\n");
return 1;
}
if (head == NULL && flag != 0) //if the node isnt empty but we are in the NULL (last) item of the node
{
printf("\n");
printf("the nodes of the list printed\n");
return;
}
printf("%d ", head->frame->duration);//prints the currect item
printf("\n");
printf("%s ", head->frame->name);//prints the currect item
printf("\n");
printf("%s ", head->frame->path);//prints the currect item
printf("\n");
print(head->next, ++flag);//calls the func recursevly
return 1;
}
void swap(struct Link **head, int value)
{
while (*head && (*head)->frame->duration != value)
{
head = (*head)->next;
}
if (*head && (*head)->next)
{
struct list *next = (*head)->next->next;
(*head)->next->next = *head;
*head = (*head)->next;
(*head)->next->next = next;
}
}
here is the print :
the print of the program

Resources