unable to reverse a linked list - c language - c

i have a simple linked list with a string, int, and next pointer in each node.
all the other linked list functions works (pop, push, delete node, etc.), but the reverse function just duplicate my node.
here is my code:
personNode* reverseList(personNode* head)
{
personNode* curr = head;
personNode* previous = NULL;
personNode* next = NULL;
while (curr != NULL)
{
next = curr->next;
curr->next = previous;
previous = curr;
curr = next;
}
head = previous;
printf("Line reversed!");
return head;
}
the results are:
Before "reversing":
and after:
(Here is The whole code:)
#include <stdio.h>
#define STR_LEN 21
typedef struct personNode
{
char name[STR_LEN];
int age;
char friends[3][STR_LEN];
struct personNode* next;
}personNode;
int recursiveLength(personNode* head, int counter);
void createPerson(char name[], int age, char friends[3][STR_LEN], personNode* head);
void link(personNode* head, personNode* toLink);
char* iHaveFriends(personNode* guest, personNode* head);
int addBehindFriend(char* friendName, personNode* guest, personNode* head);
void removePersonByName(char name[], personNode* head);
void addToListTop(personNode* VIP, personNode* head);
void search(personNode* head, char name[]);
personNode* reverseList(personNode* head);
void freeList(personNode* head);
int main(void)
{
int i = 0;
int choice = 0;
char name[STR_LEN] = { 0 };
int age = 0;
char friends[3][STR_LEN];
personNode* head = (personNode*)malloc(sizeof(personNode));
head->next = NULL;
while (choice != 7)
{
printf("\n\nWelcome to MagshiParty Line Management Software!\nPlease enter your choice from the following options :\n1 - Print line\n2 - Add person to line\n3 - Remove person from line\n4 - VIP guest\n5 - Search in line\n6 - Reverse line\n7 - Exit\n");
scanf("%d", &choice);
switch (choice)
{
case 1:
{
printf("%d people in line: \n", recursiveLength(head, 0));
recursivePrint(head);
break;
}
case 2:
{
printf("Welcome guest!");
printf("\nEnter name: ");
getchar();
scanf("%[^\t\n]s", name);
getchar();
printf("\nEnter age: ");
scanf("%d", &age);
printf("Enter names of 3 friends: ");
for (i = 0; i < 3; i++)
{
printf("\nFriend %d: ", i + 1);
getchar();
scanf("%[^\t\n]s", friends[i]);
getchar();
}
createPerson(name, age, friends, head);
break;
}
case 3:
{
printf("Enter name to remove: ");
getchar();
scanf("%[^\t\n]s", name);
getchar();
removePersonByName(name, head);
break;
}
case 4:
{
printf("VIP GUEST!\n");
printf("Enter name: ");
getchar();
scanf("%[^\t\n]s", name);
getchar();
printf("Enter age: ");
scanf("%d", &age);
personNode* newNode = (personNode*)malloc(sizeof(personNode));
newNode->age = age;
strcpy(newNode->name, name);
newNode->next = NULL;
addToListTop(newNode, head);
break;
}
case 5:
{
printf("Enter name to search: ");
getchar();
scanf("%[^t\n]s", name);
getchar();
search(head, name);
break;
}
case 6:
{
head = reverseList(head);
break;
}
case 7:
{
freeList(head);
printf("Goodbye!");
break;
}
default:
{
freeList(head);
printf("Goodbye!");
break;
}
}
}
getchar();
getchar();
return 0;
}
int recursiveLength(personNode* head, int counter)
{
personNode* curr = head;
if (head->next == NULL)
{
return counter;
}
else
{
if (curr->next != NULL)
{
counter++;
recursiveLength(curr->next, counter);
}
else
{
return counter;
}
}
}
int recursivePrint(personNode* head)
{
personNode* curr = head;
if (head->next == NULL)
{
return 0;
}
else
{
if (curr->next != NULL)
{
printf("Name: %s, Age: %d \n", curr->name, curr->age);
recursivePrint(curr->next);
}
else
{
return 0;
}
}
}
void createPerson(char name[], int age, char friends[3][STR_LEN], personNode* head)
{
int i = 0;
personNode* newNode = (personNode*)malloc(sizeof(personNode));
for (i = 0; i < 3; i++)
{
strcpy((newNode->friends[i]), friends[i]);
//printf("inserted = %s , bimkom - %s\n", (newNode->friends[i]), friends[i]);
}
newNode->age = age;
strcpy(newNode->name, name);
newNode->next = NULL;
link(head, newNode);
}
void link(personNode* head, personNode* toLink)
{
personNode* curr = head;
int i = 0;
if (head->next == NULL) // first node - list empty
{
//printf("First!");
for (i = 0; i < 3; i++)
{
strcpy((head->friends[i]), (toLink->friends[i]));
//printf("inserted = %s , bimkom - %s\n", (head->friends[i]), toLink->friends[i]);
}
//curr->next = malloc(sizeof(personNode));
curr->age = toLink->age;
strcpy(curr->name, toLink->name);
head->next = toLink;
//curr->next = NULL;
}
else
{
char foundFriend[STR_LEN] = { 0 };
strcpy(foundFriend, iHaveFriends(toLink, head));
//printf("returned from iHaveFriends: %s", foundFriend);
if (!addBehindFriend(foundFriend, toLink, head))
{
//printf("addBehindFriend Failed!");
while (curr->next != NULL)
{
curr = curr->next;
}
//curr->next = malloc(sizeof(personNode));
for (i = 0; i < 3; i++)
{
*(head->friends[i]) = toLink->friends[i];
}
curr->age = toLink->age;
strcpy(curr->name, toLink->name);
curr->next = toLink;
}
}
}
char* iHaveFriends(personNode* guest, personNode* head)
{
personNode* curr = head;
int i = 0;
char foundFriend[STR_LEN] = { 0 };
while (curr->next != NULL)
{
for (i = 0; i < 3; i++)
{
if (strcmp(curr->name, guest->friends[i]) == 0)
{
//printf("\nMATCH: %s, %s, %s\n", foundFriend, guest->friends[i], curr->name);
strcpy(foundFriend, guest->friends[i]);
}
else
{
//printf("\nProblem in friend Check!, compared: %s, %s\n", curr->name, guest->friends[i]);
}
}
//printf("\nName: %s", curr->name);
curr = curr->next;
}
//printf("\nReturning: %s", foundFriend);
return foundFriend;
}
int addBehindFriend(char* friendName, personNode* guest, personNode* head)
{
//printf("\nrecived: %s, %s\n", friendName, guest->name);
personNode* curr = head;
personNode* temp = 0;
char foundFriend[STR_LEN] = { 0 };
int flag = 0;
while (curr->next != NULL)
{
if (strcmp(friendName, curr->next->name) == 0)
{
flag = 1;
temp = curr->next;
curr->next = guest;
guest->next = temp;
}
else
{
//printf("%s, %s\n", friendName, curr->next->name);
}
curr = curr->next;
}
return flag;
}
void removePersonByName(char name[], personNode* head)
{
personNode* curr = head;
int flag = 0;
while (curr->next != NULL)
{
if (strcmp(curr->next->name, name) == 0 && curr->next->next != NULL)
{
flag = 1;
curr->next = curr->next->next;
break;
}
curr = curr->next;
}
if (flag)
{
printf("%s removed from line", name);
}
else
{
printf("%s not in line", name);
}
}
void addToListTop(personNode* VIP, personNode* head)
{
personNode* tmp = (personNode*)(malloc(sizeof(personNode)));
tmp->age = head->age;
strcpy(tmp->name, head->name);
tmp->next = head->next;
head->age = VIP->age;
strcpy(head->name, VIP->name);
head->next = tmp;
//VIP->next = tmp;
}
void search(personNode* head, char name[])
{
personNode* curr = head;
int flag = 0;
while (curr->next != NULL)
{
if (strcmp(curr->name, name) == 0)
{
flag = 1;
break;
}
curr = curr->next;
}
if (flag)
{
printf("%s found in line", name);
}
else
{
printf("%s not in line", name);
}
}
personNode* reverseList(personNode* head)
{
personNode* curr = head;
personNode* previous = NULL;
personNode* next = NULL;
while (curr != NULL)
{
next = curr->next;
curr->next = previous;
previous = curr;
curr = next;
}
head = previous;
printf("Line reversed!");
return head;
}

Your reverse function logic seems fine. There's a problem in your recursiveprint function, so here you go, try this simple one:
void print(struct personNode *head)
{
struct personNode *temp = head;
while(temp != NULL)
{
    printf("%s  ", temp->name);   
    temp = temp->next; 
}
}   

The Reverse function was not working as it should on my local machine.
It was hard to debug it so I prefered to rewrite it.
Reverse function works like this :
static personNode * reverse(struct personNode *head)
{
struct personNode* localHead = NULL;
struct personNode* temp;
struct personNode* remainingHead;
while (head != NULL)
{
remainingHead = head->next;
temp = localHead;
localHead = head;
localHead->next = temp;
head = remainingHead;
}
return localHead;
}
Regarding youre recursive print function
I am checking the head for null , not the next pointer.
int recursivePrint(personNode* head)
{
personNode* curr = head;
if (head == NULL)
{
return 0;
}
else
{
if (curr != NULL)
{
printf("Name: %s, Age: %d \n", curr->name, curr->age);
recursivePrint(curr->next);
}
else
{
return 0;
}
}
}

Related

Program received signal SIGSEGV, Segmentation fault when asking user input for doubly linked list

I am new to C programming and When I asked user to input a number for some reason my whole program gives this error
Program received signal SIGSEGV, Segmentation fault.
0x0000555555555753 in addData (word=0x7fffffffeb70 "", mode=2) at main.c:202
202 if (temp->next == NULL) {
(gdb)
HERE IS MY CODE
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#define MEMORY 6
#define MAX_word_LENGTH 11
int numberOfwords;
char words[MEMORY][MAX_word_LENGTH];
struct Node{
int data;
char *word;
struct Node *next, *prev;
};
struct Node *head, *tail;
struct Node* DlListDeleteLastNode(struct Node *head);
void addData(char *word, int mode);
void DisplayForward();
struct Node* deletePos(struct Node *head, int pos);
int getPostion(char *targetWord);
bool search(char *targetWord);
//struct Node* deletePos(struct Node *head, int pos);
int countWord(char *wording);
void insert_specified(char *wording, int pos);
int countNodes();
//void init(){
// head = NULL;
// tail = NULL;
//}
int main()
{
char name[100];
//char searchName[] = "barr";
printf("Enter number of words to be stored in the word stream: ");
int input;
scanf("%d", &input);
int i;
int count = 0;
for (i=0; i<input;i++){
count++;
printf("\nEnter name %d : ",count);
scanf ("%[^\n]%*c", name);
//scanf("%s[^\n]",words[i]);
addData(name, 2);
}
//for (int i = 0; i <4; i++) {
// strcpy(words[i],
//}
//insert_specified(searchName, 0);
//printf("%d\n", numberOfwords);
//DlListDeleteLastNode();
DisplayForward();
//int num = countNodes();
//printf("count %d", num);
//deletePos(head, 3);
//bool x = search(searchName);
//printf("%d\n", x);
//printf("%d\n", numberOfwords);
//DisplayForward();
//fflush(stdin);
printf("\nEntered names are:\n");
for(i=0;i<6;i++)
puts(words[i]);
}
int isEmpty(struct Node *h){
if(h==NULL)
return 1;
else
return 0;
}
void addData(char *word, int mode){
if (mode == 1) {
for (int i=0; i<5; i++) {
if (strcmp(words[i],word) == 0) {
//printf("found\n");
//printf("FOUND%s\n", word);
int x = getPostion(word);
//printf("index found %d/n", x);
//deletePos(head, x);
struct Node* temp = head;
struct Node* temp2 = NULL;
while (x > 1) {
temp = temp->next;
x--;
}
if (temp->next == NULL) {
head = DlListDeleteLastNode(head);
}
else {
temp2 = temp->prev;
temp2->next = temp->next;
temp->next->prev = temp2;
free(temp);
temp = NULL;
}
break;
}
//x index = getPostion()
}
if (numberOfwords >= 5) {
DlListDeleteLastNode(head);
struct Node *ptr;
ptr= malloc(sizeof *ptr);
ptr->word = malloc(sizeof(char) * 12);
//char nimI[20];
//baru->nim = malloc(12 * sizeof(char));
//strcpy(ptr->word, word);
if(head==NULL)
{
ptr->next = NULL;
ptr->prev=NULL;
strcpy(ptr->word, word);
//ptr->word= word;
head=ptr;
//head = ptr;
//tail = ptr;
}
else
{
//ptr->word=word;
strcpy(ptr->word, word);
ptr->prev=NULL;
ptr->next = head;
head->prev=ptr;
head=ptr;
}
numberOfwords++;
}
else {
struct Node *ptr;
ptr= malloc(sizeof *ptr);
ptr->word = malloc(sizeof(char) * 12);
//char nimI[20];
//baru->nim = malloc(12 * sizeof(char));
//strcpy(ptr->word, word);
if(head==NULL)
{
ptr->next = NULL;
ptr->prev=NULL;
strcpy(ptr->word, word);
//ptr->word= word;
head=ptr;
//head = ptr;
//tail = ptr;
}
else
{
//ptr->word=word;
strcpy(ptr->word, word);
ptr->prev=NULL;
ptr->next = head;
head->prev=ptr;
head=ptr;
}
numberOfwords++;
strcpy(words[numberOfwords], word);
}
}
else {
int flag = 0;
//int numWords = countNodes();
for (int i=0; i<8; i++) {
if (strcmp(words[i],word) == 0) {
//printf("found\n");
//printf("FOUND%s\n", word);
int x = getPostion(word);
//printf("index found %d/n", x);
//deletePos(head, x); //
struct Node* temp = head;
struct Node* temp2 = NULL;
while (x > 1) {
temp = temp->next;
x--;
}
if (temp->next == NULL) {
head = DlListDeleteLastNode(head);
}
else {
temp2 = temp->prev;
temp2->next = temp->next;
temp->next->prev = temp2;
free(temp);
temp = NULL;
}
flag = 1;
//DisplayForward();
//numberOfwords--;
break;
}
//x index = getPostion()
}
printf("\nflag num-> %d\n", flag);
//numberOfwords++;
int numWords = countNodes();
if (numWords >= 5 && flag==0) {
//printf("activated");
int max = 0;
char maxWord[50];
for (int i = 0; i < 8; i++) {
int num = countWord(words[i]);
if (num > max) {
max = num;
//printf("%d", max);
strcpy(maxWord, words[i]);
//printf("word %s\n", maxWord);
}
}
printf("most occured word: %s\n", maxWord);
int mostOccuredWordIndex = getPostion(maxWord);
printf("index: %d\n", mostOccuredWordIndex);
mostOccuredWordIndex--;
insert_specified(word, mostOccuredWordIndex);
DlListDeleteLastNode(head);
}
else if (numWords >= 5) {
//DlListDeleteLastNode(head);
//struct Node *ptr;
//ptr= malloc(sizeof *ptr);
//ptr->word = malloc(sizeof(char) * 12);
//char nimI[20];
//baru->nim = malloc(12 * sizeof(char));
//strcpy(ptr->word, word);
//Get most occured word in words array
//find the position of the most occured word
//int mostOccuredWordIndex = getPostion(maxWord);
//remove last element and insert new word into that position
//if position is in the last index then remove word and replace with the word
//if (mostOccuredWordIndex == 5) {
// printf("occurred");
//}
//
DlListDeleteLastNode(head);
numberOfwords = numberOfwords + 1;
struct Node *ptr;
ptr= malloc(sizeof *ptr);
ptr->word = malloc(sizeof(char) * 12);
if(head==NULL)
{
ptr->next = NULL;
ptr->prev=NULL;
strcpy(ptr->word, word);
//ptr->word= word;
head=ptr;
//head = ptr;
//tail = ptr;
}
else
{
//ptr->word=word;
strcpy(ptr->word, word);
ptr->prev=NULL;
ptr->next = head;
head->prev=ptr;
head=ptr;
}
}
else {
struct Node *ptr;
ptr= malloc(sizeof *ptr);
ptr->word = malloc(sizeof(char) * 12);
//char nimI[20];
//baru->nim = malloc(12 * sizeof(char));
//strcpy(ptr->word, word);
if(head==NULL)
{
ptr->next = NULL;
ptr->prev=NULL;
strcpy(ptr->word, word);
//ptr->word= word;
head=ptr;
//head = ptr;
//tail = ptr;
}
else
{
//ptr->word=word;
strcpy(ptr->word, word);
ptr->prev=NULL;
ptr->next = head;
head->prev=ptr;
head=ptr;
}
numberOfwords = numberOfwords + 1;
strcpy(words[numberOfwords], word);
}
DisplayForward();
numWords = countNodes();
printf("\nnumber of words%d \n", numWords);
}
}
struct Node* DlListDeleteLastNode(struct Node *head) {
struct Node *temp = head;
struct Node* temp2;
while (temp->next != NULL) {
temp = temp->next;
}
temp2 = temp->prev;
temp2->next = NULL;
free(temp);
numberOfwords--;
return head;
}
void DisplayForward() {
//Node current will point to head
struct Node *current = head;
if(head == NULL) {
printf("List is empty\n");
return;
}
printf("[");
int count = numberOfwords;
// while current->next != Null
while(current!=NULL) {
//Prints each node by incrementing pointer.
printf("%s, ", current->word);
current = current->next;
count--;
}
//current = current->next;
//printf("%s]\n", current->word);
//printf("%d", numberOfwords);
}
bool search(char *targetWord) {
int pos = 0;
if(head==NULL) {
printf("Linked List not initialized");
return;
}
struct Node *current = head;
//current = head;
while(current!=NULL) {
pos++;
if(strcmp(current->word, targetWord) == 0) {
printf("%s found at position %d\n", targetWord, pos);
return true;
}
if(current->next != NULL)
current = current->next;
else
break;
}
return false;
//printf("%s does not exist in the list\n", targetWord);
}
int getPostion(char *targetWord) {
int pos = 0;
if(head==NULL) {
printf("Linked List not initialized");
return -1;
}
struct Node *current = head;
//current = head;
while(current!=NULL) {
pos++;
if(strcmp(current->word, targetWord) == 0) {
//printf("%s found at position %d\n", targetWord, pos);
return pos;
}
if(current->next != NULL)
current = current->next;
else
break;
}
return -1;
//printf("%s does not exist in the list\n", targetWord);
}
int countWord(char *wording) {
int count = 0;
for(int i=0;i<6;i++) {
if (strcmp(words[i], wording)==0) {
//printf("found word");
count++;
}
}
return count;
}
void insert_specified(char * wording, int pos)
{
struct Node *ptr;
ptr= malloc(sizeof *ptr);
ptr->word = malloc(sizeof(char) * 12);
struct Node *temp;
int i;
if(ptr == NULL)
{
printf("\n OVERFLOW");
}
else
{
//printf("\nEnter the location\n");
//scanf("%d",&loc);
temp=head;
for(i=0;i<pos;i++)
{
temp = temp->next;
if(temp == NULL)
{
printf("\ncan't insert\n");
return;
}
}
strcpy(ptr->word, wording);
ptr->next = temp->next;
ptr -> prev = temp;
temp->next = ptr;
temp->next->prev=ptr;
printf("Node Inserted\n");
}
}
int countNodes() {
int counter = 0;
//Node current will point to head
struct Node *current = head;
while(current != NULL) {
//Increment the counter by 1 for each node
counter++;
current = current->next;
}
return counter;
}
I tried to ask the user for a number of words it wants to input for my program to store the items in a doubly linked list but instead gives a segmentation fault error
struct Node *head is a global variable which is zero initialized. In addData() you set struct Node* temp = head; and then you deference temp like your stack trace shows which will segfault.
Anyways, before you even get there the 2nd scanf() fails as it the input buffer contains the \n from reading the previous number. The syntax of the format string also looks wrong to me. In any case as you don't check the return value of you are operating on uninitialized data. Here is the minimal fix:
if(scanf(" %99[^\n]*", name) != 1) {
printf("scanf failed\n");
return 1;
}
I also replaced the hard-coded < 8 with < MEMORY to avoid a buffer overflow. Here is an example run:
Enter number of words to be stored in the word stream: 2
Enter name 1 : test
flag num-> 0
[test,
number of words1
Enter name 2 : test2
flag num-> 0
[test2, test,
number of words2
[test2, test,
Entered names are:
test
test2

C - Linked list program giving the error "Return value ignored: 'scanf'". Also please point out if you find any other mistakes

I am trying to write a code to implement a linked list. The program inserts a value taken from the user into a linked list until the user exits execution. The value can be inserted into the head, tail or any custom position entered by the user.
Upon compiling the program gives the error "Return value ignored: 'scanf'" on every scanf. It also gave an error saying scanf is unsafe, use scanf_s instead. I resolved that by adding '_CRT_SECURE_NO_WARNINGS' to preprocessor definitions. Also please point out if you find any other mistakes.
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node* next;
} node;
typedef enum position { First = 1, Custom, Last} position;
typedef enum process {Exit, Run} process;
node* insertFirst(node* ptrHead, int val)
{
node* temp = NULL;
node* newNode = (node*)malloc(sizeof(node));
if (newNode == NULL)
{
exit(1);
}
else
{
if (ptrHead == NULL)
{
newNode->data = val;
newNode->next = NULL;
ptrHead = newNode;
}
else
{
temp = ptrHead;
newNode->data = val;
newNode->next = temp;
ptrHead = newNode;
}
}
return ptrHead;
}
node* insertPos(node* ptrHead, int val, int loc)
{
node* temp = ptrHead;
node* newNode = (node*)malloc(sizeof(node));
if (newNode == NULL)
{
exit(1);
}
for (int i = 0; i < loc; i++)
{
temp = temp->next;
}
newNode->data = val;
newNode->next = temp->next;
temp->next = newNode;
return ptrHead;
}
node* insertLast(node* ptrHead, int val)
{
node* temp = ptrHead;
node* newNode = (node*)malloc(sizeof(node));
if (newNode == NULL)
{
exit(1);
}
newNode->data = val;
newNode->next = NULL;
while (temp->next != NULL)
{
temp = temp->next;
}
temp->next = newNode;
return ptrHead;
}
void printList(node* ptrHead)
{
node* temp = ptrHead;
while (temp->next != NULL)
{
printf("%d\n", temp->data);
temp = temp->next;
}
}
int countNodes(node* ptrHead)
{
node* temp = ptrHead;
int i = 0;
while (temp->next != NULL)
{
temp = temp->next;
i++;
}
return i;
}
int main()
{
node* ptrHead = NULL;
position location;
int num = 0;
int pos = 0;
process state = Run;
while (state == Run)
{
printf(" Welcome to my Linked List program. \n");
if (ptrHead == NULL)
{
printf("Enter first element of the list \n");
scanf("%d", &num);
ptrHead = insertFirst(ptrHead, num);
}
else
{
printf(" Enter number to choose location: \n 1 -> First\n 2-> Custom\n 3-> Last\n");
scanf("%d", &pos);
if (pos == Custom)
{
printf("Please enter the number and the placement\n");
scanf("%d", &num);
scanf("%d", &location);
if (location > countNodes(ptrHead))
{
printf("Enter position less than %d\n", countNodes(ptrHead));
}
else
{
ptrHead = insertPos(ptrHead, num, location);
}
}
else if (pos == First)
{
printf("Please enter the number\n");
scanf("%d", &num);
ptrHead = insertFirst(ptrHead, num);
}
else if (pos == Last)
{
printf("Please enter the number\n");
scanf("%d", &num);
ptrHead = insertLast(ptrHead, num);
}
else
{
printf("Wrong position entry\n");
}
}
printList(ptrHead);
printf("Enter '1' to insert another value and '0' to quit execution\n");
scanf("%d", &state);
}
return 0;
}

function to delete elements selected linked list C

Hi I'm creating a program for school where I have to:
Create structures
Create functions to print my linked list
Create functions to insert an ordered element
Delete elements with a minor year less than the year selected
I created all a part the last one step.
Can you help me to know what is the right way?
This is my code:
STRUCTURE:
typedef struct dimension {
int height;
int length;
} DIMENSION;
typedef struct pic {
DIMENSION d;
char name[50];
int year;
} PIC;
typedef struct node {
PIC p;
struct node *next;
} NODE;
PRINT LIST:
void printPic(PIC p) {
printf("Autor: %s\nDimension\nHeight: %d\nLength: %d\nYear: %d\n", p.name, p.d.height, p.d.length, p.year);
}
void printList(NODE *head) {
if(head->next==NULL) {
printf("No element in the list!\n");
} else {
while(head->next != NULL) {
head = head->next;
printPic(head->p);
}
}
}
NEW PIC(ORDERED WITH AREA DIMENSION)
int area(PIC p) {
return (p.d.height * p.d.length);
}
PIC createPic() {
PIC newPic;
printf("Author: ");
fgets(newPic.name, 50, stdin);
newPic.name[strlen(newPic.name)-1] = '\0';
printf("Height: ");
scanf("%d", &newPic.d.height);
printf("\n");
printf("Length: ");
scanf("%d", &newPic.d.length);
printf("\n");
printf("Year: ");
scanf("%d", &newPic.year);
printf("\n");
printf("\n");
return newPic;
}
void insertPic(NODE *head) {
NODE* newNode = malloc(sizeof(NODE));
newNode->p = createPic();
newNode->next = NULL;
if(head==NULL) {
head = newNode;
} else {
if(area(newNode->p) < area(head->p)) {
newNode->next = head;
head = newNode;
} else {
while(head->next != NULL && (area(newNode->p) > area(head->next->p))) {
head = head->next;
}
newNode->next = head->next;
head->next = newNode;
}
}
}
DELETE ELEMENTS WITH A MINOR YEAR THAN SELECTED YEAR:
Edited and now it works:
void deletePic(NODE *head, int year) {
if(head==NULL) {
printf("No element in the list!\n");
} else {
while(head->next != NULL) {
if(head->next->p.year < year) {
NODE *p = head->next;
head->next = p->next;
free(p);
} else {
head = head->next;
}
}
}
}
MAIN:
int main() {
NODE *head = malloc(sizeof(NODE));
head->next = NULL;
int choice = -1;
while(choice != 0) {
printf("Select an action:\n");
printf("Press 1 --> See list\n");
printf("Press 2 --> Insert a new element\n");
printf("Press 3 --> Delete elements with a minor year\n");
printf("Press 0 --> Stop program\n");
scanf("%d%*c", &choice);
if(choice==1) {
printList(head);
}
else if(choice==2) {
insertPic(head);
}
else if(choice==3) {
int year;
printf("Choose an year\nAll elements with a smaller year will be eliminated\n");
scanf("%d", &year);
deletePic(head, year);
}
else if(choice==0) {
printf("See you soon ;)\n");
}
}
}
Your deletePic function is broken in multiple places. Among them:
Dereferencing an indeterminate pointer, yearNode
Incorrect comparator (should use < ; not !=
free'ing an indeterminate pointer.
The first and last of those are a recipe for disaster. If that function does what the menu claims it should, I think what you want is this:
void deletePic(NODE *head, int year)
{
if (head == NULL)
{
printf("No element in the list!\n");
}
else
{
while (head->next != NULL)
{
if (head->next->p.year < year)
{
NODE *p = head->next;
head->next = p->next;
free(p);
}
else
{
head = head->next;
}
}
}
}

Add element linked list

#include <stdio.h>
#include <stdlib.h>
typedef struct str_node {
int data;
struct str_node *next;
} node;
void create_list(node ** head, int n);
void display_list(node * head);
void add_e(node ** head);
int
main(void)
{
int n;
node *head;
head = NULL;
printf("Insert size of list: ");
scanf("%d",&n);
create_list(&head, n);
display_list(head);
add_e(&head);
display_list(head);
return 0;
}
void
display_list(node *head)
{
if (head == NULL) {
printf("Empty list.");
}
else {
while (head != NULL) {
printf("DATA: %d\n", head->data);
head = head->next;
}
puts("null");
}
}
void create_list(node **head,int n){
node *new,*tmp;
int num,i;
*head = malloc(sizeof(node));
if(*head == NULL){
printf("Memory can not be allocated.");
}
else{
printf("Insert element 1: ");
scanf("%d",&num);
(*head)->data = num;
(*head)->next = NULL;
tmp = *head;
for(i=2;i<=n;i++){
new = malloc(sizeof(node));
if(new == NULL){
printf("Memory can not be allocated.");
break;
}
else{
printf("Insert element %d: ",i);
scanf("%d",&num);
new->data = num;
new->next = NULL;
tmp->next = new;
tmp = tmp->next;
}
}
}
}
void
add_e(node **head)
{
node *new;
int num;
new = malloc(sizeof(node));
if (new == NULL) {
printf("Memory can not be allocated.");
}
else {
printf("Insert element at the beginnig: ");
scanf("%d", &num);
new->data = num;
new->next = NULL;
while ((*head)->next != NULL) {
*head = (*head)->next;
}
(*head)->next = new;
}
}
I don't understand why after using the add_e() function, the display_list() function gives to me only the last two number of the list. The add_e() fucntion should be add an element at the end of the list. What am i doing wrong?
Edit: Added create_list() function so you can understand better but now it says to me to add more details so I'm writing something.
In main, n is unitialized, so you'll get random/bad results.
The add_e should not use *head in the while or even do a while. The printf says "insert at beginning", which is different/simpler. This is what I've currently coded up/fixed.
You'd want to use a loop, if you [really] wanted to insert/append to the end of the list. But, the loop would still be incorrect, because you don't want to advance head when finding the end.
I've also fixed the printf for prompts and scanf
Here's a refactored/fixed version of your code with the bugs annotated:
#include <stdio.h>
#include <stdlib.h>
typedef struct str_node {
int data;
struct str_node *next;
} node;
void create_list(node **head, int n);
void display_list(node *head);
void add_e(node ** head);
int
main(void)
{
int n;
node *head;
head = NULL;
// NOTE/BUG: n is unitialized
#if 1
n = 5;
#endif
create_list(&head, n);
display_list(head);
add_e(&head);
display_list(head);
return 0;
}
void
display_list(node *head)
{
if (head == NULL) {
printf("Empty list.");
}
else {
while (head != NULL) {
printf("DATA: %d\n", head->data);
head = head->next;
}
puts("null");
}
}
void
create_list(node **head, int n)
{
node *new,
*tmp;
int num,
i;
*head = malloc(sizeof(node));
if (*head == NULL) {
printf("Memory can not be allocated.");
}
else {
printf("Insert element 1: ");
#if 1
fflush(stdout);
#endif
#if 0
scanf("%d", &num);
#else
scanf(" %d", &num);
#endif
(*head)->data = num;
(*head)->next = NULL;
tmp = *head;
for (i = 2; i <= n; i++) {
new = malloc(sizeof(node));
if (new == NULL) {
printf("Memory can not be allocated.");
break;
}
else {
printf("Insert element %d: ", i);
#if 1
fflush(stdout);
#endif
#if 0
scanf("%d", &num);
#else
scanf(" %d", &num);
#endif
new->data = num;
new->next = NULL;
tmp->next = new;
tmp = tmp->next;
}
}
}
}
void
add_e(node **head)
{
node *new;
int num;
new = malloc(sizeof(node));
if (new == NULL) {
printf("Memory can not be allocated.");
}
else {
printf("Insert element at the beginnig: ");
fflush(stdout);
scanf(" %d", &num);
new->data = num;
new->next = NULL;
#if 0
while ((*head)->next != NULL) {
*head = (*head)->next;
}
(*head)->next = new;
#else
if (*head == NULL)
*head = new;
else {
new->next = *head;
*head = new;
}
#endif
}
}
UPDATE:
In add_e, because I couldn't be sure if you wanted to insert at beginning of list [based on the printf] or at the end [based on the code], I created a version that is cleaned up a bit more and demonstrates both types:
#include <stdio.h>
#include <stdlib.h>
typedef struct str_node {
int data;
struct str_node *next;
} node;
void create_list(node **head, int n);
void display_list(node *head);
void add_begin(node **head);
void add_end(node **head);
int
main(void)
{
int n;
node *head;
setbuf(stdout,NULL);
head = NULL;
printf("Enter initial number of list elements: ");
scanf(" %d",&n);
create_list(&head, n);
display_list(head);
add_begin(&head);
display_list(head);
add_end(&head);
display_list(head);
return 0;
}
void
display_list(node *head)
{
node *cur;
if (head == NULL) {
printf("Empty list.\n");
}
for (cur = head; cur != NULL; cur = cur->next)
printf("DATA: %d\n", cur->data);
}
void
create_list(node **head, int n)
{
node *new, *tmp;
int num, i;
tmp = *head;
for (i = 1; i <= n; i++) {
new = malloc(sizeof(node));
if (new == NULL) {
printf("Memory can not be allocated.");
break;
}
printf("Insert element %d: ", i);
scanf(" %d", &num);
new->data = num;
new->next = NULL;
if (*head == NULL)
*head = new;
else
tmp->next = new;
tmp = new;
}
}
// add_begin -- insert at before head of list
void
add_begin(node **head)
{
node *new;
int num;
new = malloc(sizeof(node));
if (new == NULL) {
printf("Memory can not be allocated.");
exit(1);
}
printf("Insert element at the beginning: ");
scanf(" %d", &num);
new->data = num;
new->next = *head;
*head = new;
}
// add_end -- add to tail/end of list
void
add_end(node **head)
{
node *new;
node *tmp;
node *tail;
int num;
new = malloc(sizeof(node));
if (new == NULL) {
printf("Memory can not be allocated.");
exit(1);
}
printf("Append element at the end: ");
scanf(" %d", &num);
new->data = num;
new->next = NULL;
// find the tail
tail = NULL;
for (tmp = *head; tmp != NULL; tmp = tmp->next)
tail = tmp;
if (tail != NULL)
tail->next = new;
else
*head = new;
}

LinkedList with Char (String Issue

So I'm having issue with my code with the structure I'm using. I would like my structure to be able add,retrieve or sort but I'm getting a lot of problem with the structure. It work if I use only number but I need to user 3 string. One for firstname, lastname and phonenumber but I can't figure.
This is the code I'm having right now:
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
char first[15];
char last[15];
char phone[12];
struct node *next;
}*head;
void append(int num, char f[15], char l[15],char p[12])
{
struct node *temp, *right;
temp = (struct node *)malloc(sizeof(struct node));
temp->data = num;
strcpy(temp->first, f);
strcpy(temp->last, l);
strcpy(temp->phone, p);
right = (struct node *)head;
while (right->next != NULL)
right = right->next;
right->next = temp;
right = temp;
right->next = NULL;
}
void add(int num, char f[15], char l[15],char p[12])
{
struct node *temp;
temp = (struct node *)malloc(sizeof(struct node));
temp->data = num;
strcpy(temp->first, f);
strcpy(temp->last, l);
strcpy(temp->phone, p);
if (head == NULL)
{
head = temp;
head->next = NULL;
}
else
{
temp->next = head;
head = temp;
}
}
void addafter(int num, char f[15], char l[15],char p[12],int loc)
{
int i;
struct node *temp, *left, *right;
right = head;
for (i = 1; i<loc; i++)
{
left = right;
right = right->next;
}
temp = (struct node *)malloc(sizeof(struct node));
temp->data = num;
strcpy(temp->first, f);
strcpy(temp->last, l);
strcpy(temp->phone, p);
left->next = temp;
left = temp;
left->next = right;
return;
}
void insert(int num, char f[15], char l[15],char p[12])
{
int c = 0;
struct node *temp;
temp = head;
if (temp == NULL)
{
add(num,f,l,p);
}
else
{
while (temp != NULL)
{
if (temp->data<num)
c++;
temp = temp->next;
}
if (c == 0)
add(num,f,l,p);
else if (c<count())
addafter(num,f,l,p, ++c);
else
append(num,f,l,p);
}
}
int delete(int num)
{
struct node *temp, *prev;
temp = head;
while (temp != NULL)
{
if (temp->data == num)
{
if (temp == head)
{
head = temp->next;
free(temp);
return 1;
}
else
{
prev->next = temp->next;
free(temp);
return 1;
}
}
else
{
prev = temp;
temp = temp->next;
}
}
return 0;
}
void display(struct node *r)
{
r = head;
if (r == NULL)
{
return;
}
while (r != NULL)
{
printf("%d ", r->data);
r = r->next;
}
printf("\n");
}
int count()
{
struct node *n;
int c = 0;
n = head;
while (n != NULL)
{
n = n->next;
c++;
}
return c;
}
int main()
{
int i, num;
char fname[15], lname[15], phone[12];
struct node *n;
head = NULL;
while (1)
{
printf("\nList Operations\n");
printf("===============\n");
printf("1.Insert\n");
printf("2.Display\n");
printf("3.Retrieve\n");
printf("4.Delete\n");
printf("5.Exit\n");
printf("Enter your choice : ");
if (scanf("%d", &i) <= 0){
printf("Enter only an Integer\n");
exit(0);
}
else {
switch (i)
{
case 1:
printf("Enter the id, first, last and phone (Separte with space) : ");
scanf("%d %s %s %s", &num,fname,lname,phone);
insert(num,fname,lname,phone);
break;
case 2:
if (head == NULL){
printf("List is Empty\n");
}else{
printf("Element(s) in the list are : ");
}
display(n);
break;
case 3:
//To be made
//scanf("Retrieve this : %d\n", count());
break;
case 4:
if (head == NULL){
printf("List is Empty\n");
}else{
printf("Enter the number to delete : ");
scanf("%d", &num);
if (delete(num))
printf("%d deleted successfully\n", num);
else
printf("%d not found in the list\n", num);
}
break;
case 5:
return 0;
default:
printf("Invalid option\n");
}
}
}
return 0;
}
Thanks for anyone that could explain me the issue and or fix it.
Everywhere you have:
temp->data = num;
add the lines
strcpy(temp->first, f);
strcpy(temp->last, l);
strcpy(temp->phone, p);

Resources