I need this program to stop asking for flavors when the word "lemon" is said. For some reason, I can't get it to work correctly. I have tried to add an "if" statement for it but it wasn't working out correctly. The code will stop asking for flavor for a split sentence and then will start asking for it again and it will go all the way to 15 flavors instead of stopping at the flavor "lemon".
#include <stdio.h>
#include <string.h>
#include<stdlib.h>
typedef struct node {
void *data;
int d;
struct node *next;
}node;
node * createLinkedList(char [][20], int);//function to create linked list for all flavours
node * createLinkedListPrice(int ar[], int);//function to declare linkedlist for all prices
int main(void) {
int c= 1;//count of input flavors
char allFlavors[16][20];
int allPrice[16];
char ch[] = "lemon";
while(c != 16) {//taking input flavors and prices
char flavorName[20];
printf("Enter flavor %d name:", c);
scanf("%s", flavorName);
if(!(strcmp(flavorName,ch)) && c > 5) {
break;
}
else if(!(strcmp(flavorName,ch)) && c <= 5) {
continue;
}
int price;
printf("Enter flavor %d price in $", c);
scanf("%d", &price);
strcpy(allFlavors[c], flavorName); //storing all flavors in array of strings
allPrice[c] = price;//storing all prices in array
c += 1;//This variable is to keep track of count of input
}
while(1) {
char instruct[5];
printf("Do u want icecream:");
scanf("%s", instruct);
if(!strcmp(instruct,"no"))//If the given instruction is no then break
break;
else {//If given instruction is yes then calculate the cost of flavour
char flav[20];
int scoops;
int cost = 0;
printf("Which flavor do u want\n");
scanf("%s", flav);
printf("How many scoops:");
scanf("%d", &scoops);
node *head = createLinkedList(allFlavors,c);//calling all flavors function for head
node *priceHead = createLinkedListPrice(allPrice,c);//calling all price function for head
while(head != NULL) {//searching for the flavour in the linkedlist
if(!strcmp(head->data,flav)) {//If flavour is found then add the price to cost
cost += (scoops * priceHead->d);
break;
}
priceHead = priceHead->next;
head = head->next;
}
printf("cost is $%d\n", cost);
}
}
}
node * createLinkedList(char allFlavors[][20], int n) {//creates linkedlist of all flavors and returns head
node * head = NULL;
node * temp = NULL;
node * ptr = NULL;
for(int pd = 1; pd < n; pd++) {
temp = (node*)malloc(sizeof(node));
temp->data = allFlavors[pd];
temp->next = NULL;
if (head == NULL)
head= temp;
else {
ptr=head;
while(ptr->next!=NULL) {
ptr=ptr->next;
}
ptr->next=temp;
}
}
return head;
}
node * createLinkedListPrice(int ar[], int n) {//creates linkedlist of all prices and returns head
node * head = NULL;
node * temp = NULL;
node * ptr = NULL;
for(int pd = 1; pd < n; pd++) {
temp = (node*)malloc(sizeof(node));
temp->d = ar[pd];
temp->next = NULL;
if (head == NULL)
head= temp;
else {
ptr=head;
while(ptr->next!=NULL) {
ptr=ptr->next;
}
ptr->next=temp;
}
}
return head;
}
Related
I am a beginner to C and am learning linked lists. I tried making functions to have everything organised but no matter what i do the function print_list doesn't print the values. The output is only START and END. I noticed that if I put the same block of code directly into the function that builds the lists, then it prints correctly. What am I doing wrong? (Also first time asking on stack overflow)
Thank you to whoever answers.
#include <stdlib.h>
#include <stdio.h>
typedef struct nd
{
int val;
struct nd *next;
} node;
typedef node * Lista;
void print_list(node*currnode)
{
printf("START -> ");
while (currnode != NULL)
{
printf("%d -> ", currnode->val);
currnode = currnode->next;
}
printf("END");
}
//reimpilista means "buildlist"
node*riempilista(Lista lis){
node *currentNode, *temp;
int i,n;
printf("how many nodes?\n");
scanf("%d",&n);
for (i = 0; i < n; i++)
{
currentNode = (node *)malloc(sizeof(node));
printf("Enter element %d : ", (i + 1));
scanf("%d", ¤tNode->val);
if (i == 0)
{
temp = currentNode;
}
else
{
temp->next = currentNode;
temp = currentNode;
}
}
temp->next = NULL;
return lis;
}
int main(){
Lista listautente=NULL;
listautente=riempilista(listautente);
print_list(listautente);
return 0;
}
When you build the list you need to return the head of the list as a result. So you need to store the pointer to the first node. Then when adding a new node you need to know the previous node, so you need to store it as well. The last added node should have next field poiting to NULL otherwise you won't be able to determine the end of the list and will get an exception.
Here is your code slightly edited.
#include <stdlib.h>
#include <stdio.h>
typedef struct nd {
int val;
struct nd *next;
} node;
typedef node *Lista;
void print_list(node *currnode) {
printf("START -> ");
while (currnode != NULL) {
printf("%d -> ", currnode->val);
currnode = currnode->next;
}
printf("END");
}
//reimpilista means "buildlist"
node *riempilista() {
node *firstNode = NULL, *currentNode = NULL, *previousNode = NULL;
int i, n;
printf("how many nodes?\n");
scanf("%d", &n);
for (i = 0; i < n; ++i) {
currentNode = (node *)malloc(sizeof(node));
printf("Enter element %d : ", (i + 1));
scanf("%d", ¤tNode->val);
currentNode->next = NULL;
if (i == 0) {
firstNode = currentNode;
}
if (previousNode != NULL) {
previousNode->next = currentNode;
}
previousNode = currentNode;
}
return firstNode;
}
int main() {
Lista listautente = riempilista();
print_list(listautente);
return 0;
}
I tried to fix your program with minimal changes. Here it is:
Change
node *currentNode, *temp;
to
node *currentNode, *temp, *head;
Change
temp = currentNode;
to
temp = currentNode; head = temp;
Change
return lis;
to
return head;
Here is the link to the modified code:
https://onlinegdb.com/8cjqifgl2
I have an array of linked list which I am trying to reverse recursively. When I call the function to reverse it will not reverse all of the nodes but rather a couple of the nodes.
The reverse function appears to be deleting the first node (base case) and filling its spot with the last node (end of sub case). I think that the problem lies in the calling of the for loop within the reverse_nodes function however that doesn't seem to fix it.
Here is some output..
pre-reverse function:
-----
group 0
alice, 2
-----
group 1
martin, 4
-----
group 2
keanu, 6
-----
group 3
miles, 8
post - reverse function
-----
group 0
miles, 8
-----
group 1
martin, 4
-----
group 2
keanu, 6
-----
group 3
miles, 8
I am trying to get it to reverse to that it reads: 8,6,4,2
Please note I have only included relevant code blocks such as the struct architecture, the head/tail construction, the deletion of all nodes prior to reading in the binary file, reading binary file to nodes, and the main function. Can I get some help figuring out what in the reverse function is causing it to not completely reverse? Thank for your time. See code below!
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct node
{
char name[20];
int size;
struct node *next;
}node;
node* head[4]={NULL,NULL,NULL,NULL};
node* tail[4]={NULL,NULL,NULL,NULL};
void wipe_nodes()
{
int i;
node *p=NULL;
for(i=4; i>0; i--)
{
p=head[i];
if(p == NULL)
{
printf("Nodes are clear!\n");
}
while(p != NULL)
{
delete_party(p->name, p->size); // cant call name and size
p = p -> next;
}
}
}
void bin_to_list(char *filename)
{
FILE *fp;
int ret;
fp = fopen(filename, "rb");
if (fp == NULL)
{
printf("Null file!\n");
return;
}
node temp;
//temp = (node *)malloc(sizeof(node));
while((ret = fread(&temp, sizeof(node), 1, fp) > 0))
{
printf("%s %d", temp.name, temp.size);
if(temp.size == 0)
{
printf("\nThat is not a valid command. Party not added!\n");
}
if(temp.size >= 1 && temp.size <= 2)
{
add_party(0, temp.name, temp.size);
}
else if(temp.size >= 3 && temp.size <= 4)
{
add_party(1, temp.name, temp.size);
}
else if(temp.size >= 5 && temp.size <= 6)
{
add_party(2, temp.name, temp.size);
}
else if(temp.size >= 7)
{
add_party(3, temp.name, temp.size);
}
}
fclose(fp);
return;
}
void reverse_nodes(node *p, node *q)
{
int i;
for(i=0; i<4; i++)
{
//node *p=head[i];
if(p == NULL)
{
printf("Error, no nodes!\n");
return;
}
if (p->next == NULL)
{
printf("LOL, only one node! Can't reverse!\n");
head[i] = p;
}
else
{
reverse_nodes(p->next, p);
}
p->next = q;
return;
int main(int argc, char *argv[])
{
int x, i;
read_to_list(argv[1]);
bin_to_list(argv[2]);
while (1)
{
fflush(stdin);
printf("\n\nEnter 1 to add a party\nEnter 2 to remove a party\nEnter 3 for the list of the party\nEnter 4 to change party size.\nEnter 5 to quit (write to .txt file).\nEnter 6 to read from bin file.\nEnter 7 to reverse the list.\n\n");
scanf("%d",&x);
char name[20];
int size;
switch(x)
{
case 1:
printf("\nParty Name: ");
scanf("%s", name);
printf("\nParty Size: ");
scanf("%d", &size);
if(size == 0)
{
printf("\nThat is not a valid command. Party not added!\n");
}
if(size >= 1 && size <= 2)
{
add_party(0, name, size);
}
else if(size >= 3 && size <= 4)
{
add_party(1, name, size);
}
else if(size >= 5 && size <= 6)
{
add_party(2, name, size);
}
else if(size >= 7)
{
add_party(3, name, size);
}
break;
case 2:
printf("\nSize of party to delete: ");
scanf("%i", &size);
delete_party(NULL, size);
break;
case 3:
list_parties();
break;
case 4:
change_partysize(name, size);
break;
case 5:
write_to_file(argv[1]);
write_to_bin(argv[2]);
exit(0);
break;
case 6:
wipe_nodes();
bin_to_list(argv[2]);
break;
case 7:
for(i=0; i<4; i++)
{
reverse_nodes(head[i], NULL);
}
break;
default:
continue;
}
}
}
#include<stdio.h>
#include<stdlib.h>
/* Link list node */
struct Node
{
int data;
struct Node* next;
};
/* Function to reverse the linked list */
static void reverse(struct Node** head_ref)
{
struct Node* prev = NULL;
struct Node* current = *head_ref;
struct Node* next;
while (current != NULL)
{
next = current->next;
current->next = prev;
prev = current;
current = next;
}
*head_ref = prev;
}
/* Function to push a node */
void push(struct Node** head_ref, int new_data)
{
/* allocate node */
struct Node* new_node =
(struct Node*) malloc(sizeof(struct Node));
/* put in the data */
new_node->data = new_data;
/* link the old list off the new node */
new_node->next = (*head_ref);
/* move the head to point to the new node */
(*head_ref) = new_node;
}
/* Function to print linked list */
void printList(struct Node *head)
{
struct Node *temp = head;
while(temp != NULL)
{
printf("%d ", temp->data);
temp = temp->next;
}
}
/* Driver program to test above function*/
int main()
{
/* Start with the empty list */
struct Node* head = NULL;
push(&head, 20);
push(&head, 4);
push(&head, 15);
push(&head, 85);
printf("Given linked list\n");
printList(head);
reverse(&head);
printf("\nReversed Linked list \n");
printList(head);
getchar();
}
Your reverse_nodes function is just setting the next member of the node, not the current node, so when it gets to the end of the list, it will set the next of the last member to the previous member in the linked list but leave the last member untouched.
This worked for me:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct node
{
char name[20];
int size;
struct node *next;
}node;
node* head;
void reverse_nodes(node ** pphead)
{
node *prev = NULL;
node *current = *pphead;
node *next;
while (current != NULL)
{
next = current->next;
current->next = prev;
prev = current;
current = next;
}
*pphead = prev;
}
void main(void)
{
int i;
node * phead;
head = phead = (node *)malloc(sizeof(node));
phead->size = 0;
for (i = 0; i < 4; i++)
{
node * p;
phead->next = (node *)malloc(sizeof(node));
phead = phead->next;
phead->size = i + 1;
phead->next = NULL;
}
reverse_nodes(&head);
phead = head;
while (phead)
{
printf("%d\r\n", phead->size);
phead = phead->next;
}
}
Edit:
Recursion is usually a bad idea as you could end up blowing the stack - it's always best to try and do what you need to do in a single (or multiple if required) function(s) if possible, which in this case is easily possible.
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
struct node *insert(struct node *link, int data) {
if (link == NULL) {
link = (struct node *)malloc(sizeof(struct node));
link->data = data;
link->next = NULL;
} else {
struct node *newlink = (struct node *)malloc(sizeof(struct node));
newlink->data = data;
newlink->next = link;
link = newlink;
}
return link;
}
void reverse(struct node *link) {
int i, j = 0;
int arr1[100], arr2[100];
struct node *current;
int count = 0;
current = link;
while (current != NULL) {
arr1[i] = current->data;
i = i + 1;
count = count + 1;
current = current->next;
}
printf("\n");
i = 0;
j = 0;
for (i = count - 1; i >= 0; i--) {
arr2[j] = arr1[i];
j = j + 1;
}
printf("The elements in the linked list are: ");
for (i = 0; i < count; i++) {
printf("%d ", arr1[i]);
}
printf("The elements in the reversed linked list are: ");
for (j = 0; j < count; i++) {
printf("%d ", arr2[j]);
}
}
void print(struct node *link) {
struct node *temp = link;
printf("The elements in the linked list are: ");
while (temp != NULL) {
printf("%d ", temp->data);
temp = temp->next;
}
}
void main() {
int value;
printf("Enter the value:\n");
scanf("%d", &value);
struct node *link = NULL;
link = insert(link, value);
char ans[3] = "yes";
while (ans[0] == 'y') {
printf("Do you want to add another node? Type Yes/No\n");
scanf("%s", ans);
if (ans[0] == 'y') {
printf("Enter the value:\n");
scanf("%d", &value);
link = insert(link, value);
} else {
reverse(link);
}
}
}
Here is the code I wrote to reverse a single linked list in C. I seem to try different combinations of the program but while doing it by array method, I am unable to get rid of the segmentation fault, and hence it doesn't give output.
There are some problems in your code:
i is uninitialized when used in the while loop in function reverse, causing undefined behavior which could explain the segmentation fault.
j is not modified in the loop at the end of the reverse function, causing an infinite loop:
for (j = 0; j < count; i++) {
printf("%d ", arr2[j]);
}
you are not reversing the list, you just print the list contents in reverse order, and assume its length is at most 100. This is probably not what you are expected to do.
in function main, the array ans should be made larger to accommodate at least the word yes, and you should prevent scanf() from storing more characters into it than would fit. Also reorganize the code to avoid duplication:
int main(void) {
struct node *link = NULL;
for (;;) {
char ans[80];
int value;
printf("Enter the value:\n");
if (scanf("%d", &value) != 1)
break;
link = insert(link, value);
printf("Do you want to add another node? Type Yes/No\n");
if (scanf("%79s", ans) != 1 || ans[0] != 'y') {
break;
}
}
reverse(link);
return 0;
}
Most of the above problems would have been spotted immediately by increasing the compiler warning level (for example gcc -Wall -Werror or clang -Weverything -Werror).
Here is a simpler version that reads numbers and allocates the list in the same order as you do, inserting each new element before the previous one, then reverses the list and finally prints it. As expected, the list is printed in the order of entry.
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
struct node *insert(struct node *head, int data) {
struct node *newlink = malloc(sizeof(*newlink));
newlink->data = data;
newlink->next = head;
return newlink;
}
struct node *reverse(struct node *link) {
struct node *prev = NULL;
while (link) {
struct node *temp = link->next;
link->next = prev;
prev = link;
link = temp;
}
return prev;
}
void print(struct node *link) {
printf("The elements in the linked list are: ");
for (struct node *n = link; n; n = n->next) {
printf("%d ", n->data);
}
printf("\n");
}
int main(void) {
struct node *link = NULL;
int value;
printf("Enter the values, end the list with 0:\n");
while (scanf("%d", &value) == 1 && value != 0) {
link = insert(link, value);
}
link = reverse(link);
print(link);
return 0;
}
The question I came across.
Here is what I have done so far
#include <stdio.h>
#include <stdlib.h>
struct node
{
int digit;
struct node *next;
};
struct node *make_node(int num, struct node *head);
struct node *newNode(int digit);
struct node *sum(struct node *num1, struct node *num2);
void print(struct node *node);
int main()
{
int a, b;
struct node *new_nodeA1 = NULL, *new_nodeA2 = NULL;
struct node *new_nodeB1 = NULL, *new_nodeB2 = NULL;
struct node *res = NULL;
printf("\nEnter no. of digits for your two numbers (separate with space) ");
scanf("%d %d", &a, &b);
int n1[a], n2[b];
printf("\n\nEnter first non-negative integer to add: ");
for (int j = 0; j < a; j++)
scanf("%1d", &n1[j]);
printf("Enter second non-negative integer to add: ");
for (int k = 0; k < b; k++)
scanf("%1d", &n2[k]);
/* for (int i = 0; i <= a - 1; i++)
printf("%d\n", n1[i]);
printf("%d\n", a); */
for (int z = 0; z < a - 1; z++)
{
new_nodeA2 = make_node(n1[z], new_nodeA1);
/*new_nodeA2 = newNode(n1[z]);*/
if (new_nodeA1 == NULL)
new_nodeA1 = new_nodeA2;
}
for (int y = 0; y < b - 1; y++)
{
new_nodeB2 = make_node(n2[y], new_nodeB1);
if (new_nodeB1 == NULL)
new_nodeB1 = new_nodeB2;
}
printf("\n");
print(new_nodeA1);
printf("\n");
print(new_nodeB1);
printf("\n")
res = sum(new_nodeA2, new_nodeB2);
printf("Result: ");
print(res);
return 0;
}
struct node *make_node(int num, struct node *head)
{
struct node *temp = malloc(sizeof(struct node));
if (temp == NULL)
{
fprintf(stderr, "Call of malloc() failed\n");
exit(1);
}
if (head != NULL)
head->next = temp;
temp->digit = num;
temp->next = NULL;
return temp;
}
struct node *newNode(int digit)
{
struct node *new_node = (struct node *) malloc(sizeof(struct node));
new_node->digit = digit;
new_node->next = NULL;
return new_node;
}
struct node *sum(struct node *num1, struct node *num2)
{
struct node *res = NULL;
struct node *temp, *prev = NULL;
int carry = 0, sum;
while (num1 != NULL || num2 != NULL)
{
sum = carry + (num1? num1->digit: 0) + (num2? num2->digit: 0);
carry = (sum >= 10)? 1 : 0;
sum = sum % 10;
temp = newNode(sum);
if(res == NULL)
res = temp;
else
prev->next = temp;
prev = temp;
if (num1)
num1 = num1->next;
if (num2)
num2 = num2->next;
}
if (carry > 0)
temp->next = newNode(carry);
return res;
}
void print(struct node *node)
{
while(node != NULL)
{
printf("%d->", node->digit);
node = node->next;
}
printf("\n");
}
My Output
My compiler does not give me any error. I tried debugging my make_node function but I cant catch the problem as to why my nodes are skipping certain digits.
Your linked list insert code is very broken. For this style of list, you need to walk down the list from head->next until a null is found and insert there. Instead, you are always replacing the head->next with your new temp node, thus breaking the list.
You can also add to the list backwards, making the newly added item the head each time and thus get around the traversal for add, but beware this will place your numbers in reverse order (which actually helps when you do your adding, so perhaps this is good too.)
I am trying to write a program that creates and displays linked lists, and allows people to insert an element at the beginning, middle or end.
Insertion at the beginning or the middle works perfectly. However, my program fails when it comes to inserting at the end. Please have a look and tell me where I am going wrong or what needs modification. Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
struct node {
int number;
struct node *next;
};
typedef struct node NODE;
NODE *node1, *start, *rear, *m, *nodex, *temp1;
int main() {
int i, n1, n2;
start = NULL;
printf("Enter the number of inputs to the list:");
scanf("%d", &n1);
for (i = 0; i < n1; i++) {
// node creation begins here
node1 = (NODE*) malloc(sizeof(NODE));
int inf;
printf("Enter node value:");
scanf("%d", &inf);
node1->number = inf;
node1->next = NULL;
if (start == NULL) {
// first node creation
start = rear = node1;
} else {
m = start;
if (m->number > inf) {
// for insertion in beginning
node1->next = m;
start = node1;
} else {
while (m->next->number < inf) {
// searching to insert in middle of sorted list
m = m->next;
}
temp1 = m->next;
m->next = node1;
node1->next = temp1;
}
}
display(); // to display the linked list
}
return 0;
}
void display() {
nodex = start;
while (nodex != NULL) {
printf("%d ->", nodex->number);
nodex = nodex->next;
}
}
What happens at the end of the list?
while(m->next->number < inf){
//searching to insert in middle of sorted list
m=m->next;
}
This check fails when m->next is NULL. NULL->something fails. So do a check if it's a valid pointer, like:
while(m->next)
if(m->next->number < inf)
m=m->next;
else
break;