Nested singly linked list - c

This function which is supposed to add items to clients isn't working for me. The rest seems to be working properly.
#include <stdio.h>
#include <stdlib.h>
struct item{
char item_name[30];
struct item *NextItem;
};
struct client{
struct client *NextClient;
char name[30];
char last_name[30];
struct item *firstItem;
struct item *lastItem;
};
struct client *head = NULL;
/////////////////////////////
struct client* FindTailClient(struct client* head)
{
struct client *temp = head;
while( temp->NextClient != NULL)
{
temp = temp->NextClient;
}
return temp;
}
/////////////////////////////
////////
struct client *GetClientData()
{
char data[30];
struct client *temp;
temp = (struct client*)malloc(sizeof(struct client));
printf("Enter the person's name--->");
scanf("%s",data);
strcpy(temp->name,data);
printf("Enter the person's last name--->");
scanf("%s",data);
strcpy(temp->last_name,data);
temp->NextClient = NULL;
return temp;
}
///////////
struct item *GetItemData()
{
struct item *temp;
char data[30];
temp = (struct item*)malloc(sizeof(struct item));
printf("Enter the item name--->");
scanf("%s",data);
strcpy(temp->item_name,data);
temp->NextItem = NULL;
return temp;
}
///////////
//////////////
struct client* AddClient()
{
struct client *temp,temp1;
temp=head;
struct client *data = GetClientData();
if(head == NULL)
{
head=data;
head->NextClient = NULL;
}
else
{
while(temp->NextClient != NULL)
{
temp=temp->NextClient;
}
data->NextClient=NULL;
temp->NextClient=data;
}
}
///////////////////
void display()
{
struct client *temp=head;
if(temp==NULL)
{
printf("\nList is Empty");
}
else
{
printf("\nElements in the List: ");
while(temp!=NULL)
{
printf(" -> %s ->%s ",temp->name,temp->last_name);
temp=temp->NextClient;
}
printf("\n");
}
}
///////////////////
void AddItemToClient(struct client* head, struct item *item)
{
item->NextItem = NULL;
if(head->firstItem == NULL) {
head->firstItem = item;
} else {
head->firstItem->NextItem = item;
}
head->lastItem = item;
}
///////////////////
struct client *find(struct client *head, char name[])
{
while (head->NextClient != NULL )
{
if (strcmp(head->name,name) == 0)
{
printf("Target found: %s\n",head->name);
return head;
}
head = head->NextClient;
}
printf("target not found");
return NULL;
}
//////////////////
int main()
{
int i;
char data[30];
char name[30];
struct client *temp;
struct client *head;
struct item *data1;
for(i=0;i<2;i++)
{
AddClient();
}
display();
printf("Insert name to find:");
scanf("%s",name);
temp = find(&head,name);
data1 = GetItemData();
AddItemToClient(temp,&data1);
display();
}

This is wrong
void AddItemToClient(struct client* head, struct item *item)
{
item->NextItem = NULL;
if(head->firstItem == NULL) {
head->firstItem = item;
} else {
head->firstItem->NextItem = item;
}
head->lastItem = item;
}
Should be
void AddItemToClient(struct client* head, struct item *item)
{
item->NextItem = NULL;
if(head->firstItem == NULL) {
head->firstItem = item;
} else {
head->lastItem->NextItem = item;
}
head->lastItem = item;
}

Related

I am trying to reverse a linked list using recursion in C, I have some doubts on my recursive function

Below is the program
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
};
struct node *head;
struct node* reverse_ll(struct node* hnode)
{
if(hnode == 0)
{
return 0;
}
if(hnode->next == 0)
{
head=hnode;
return hnode;
}
struct node* ptr=reverse_ll(hnode->next);
ptr->next=hnode;
hnode->next=0;
//return hnode;
}
void display()
{
struct node *ptr;
ptr=head;
if(ptr==0)
{
printf("empty");
}
else
{
while(ptr!=0)
{
printf("%d->",ptr->data);
ptr=ptr->next;
}
printf("null");
}
}
int main()
{
struct node* h;
lastinsert(1);
lastinsert(2);
lastinsert(3);
lastinsert(4);
lastinsert(5);
display();
h=reverse_ll(head);
display();
return 0;
}
In function reverse_ll() even if I comment "return hnode" I am getting the right output How is it possible where does ptr receives its address from when I comment "return hnode"?
output: 1->2->3->4->5->null
5->4->3->2->1->null
reverse_ll() must return a struct node * in the recursive case:
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
struct node *head;
void lastinsert(int data) {
struct node **c = &head;
for(; *c; c = &(*c)->next);
*c = malloc(sizeof(*head));
if (!(*c)) {
printf("malloc failed\n");
return;
}
(*c)->data = data;
(*c)->next = NULL;
}
struct node *reverse_ll(struct node* hnode) {
if(!hnode)
return NULL;
if(!hnode->next) {
head = hnode;
return hnode;
}
struct node *ptr=reverse_ll(hnode->next);
ptr->next=hnode;
hnode->next = NULL;
return hnode;
}
void display() {
if(!head) {
printf("empty");
return;
}
for(struct node *ptr = head; ptr; ptr = ptr->next) {
printf("%d->",ptr->data);
}
printf("null\n");
}
int main() {
for(int i = 1; i <= 5; i++) {
lastinsert(i);
}
display();
reverse_ll(head);
display();
// It's good practice to implement a function that frees you list
// which you would call here.
return 0;
}
and example run:
$ ./a.out
1->2->3->4->5->null
5->4->3->2->1->null

Why does the following code display a blank linked list?

Why does the following code display a blank linked list? I want to insert single characters to each node in the linked list. The characters are from the ch string. It works fine when I change the node member sc to integer and modify the associated code. But it seems there is an issue with using characters.
#include <stdio.h>
#include <string.h>
struct node {
char sc[1];
struct node *next;
};
char ch[30];
void insert(struct node **head_ref,int j) {
struct node *new_node = (struct node*)malloc(sizeof(struct node));
struct node *last = *head_ref;
new_node->sc[0] = ch[j];
new_node->next = NULL;
if (*head_ref == NULL) {
*head_ref=new_node;
return;
}
while (last->next != NULL) {
last = last->next;
}
last->next = new_node;
return;
}
void display(struct node *head) {
struct node *t = head;
while (t != NULL) {
printf("%s", t->sc);
t = t->next;
}
}
main() {
FILE *fp;
fp = fopen("C:\\Users\\Jefferson Warie\\Desktop\\input.txt", "r");
if (fp == NULL) {
printf("File could not be opened.");
}
struct node *num1h;
num1h = NULL;
int i = 0, j;
char arr[100][30];
char ch[30];
while (!feof(fp)) {
fgets(arr[i], 31, fp);
i++;
}
for (i = 0; i < 2; i++) {
strcpy(ch, arr[i]);
for (j = 0; ch[j] != '\0'; j++) {
if (i == 0) {
insert(&num1h, j);
}
}
}
printf("First linked list: ");
display(num1h);
}
You have declared character array ch twice — once as a global variable and once local to main.
Also, you need to add #include<stdlib.h> to use malloc
This is the final updated code.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct node {
char sc[1];
struct node *next;
};
char ch[30];
void insert(struct node **head_ref,int j) {
struct node *new_node=(struct node*)malloc(sizeof(struct node));
struct node *last=*head_ref;
new_node->sc[0]=ch[j];
new_node->next=NULL;
if (*head_ref==NULL) {
*head_ref=new_node;
return;
}
while(last->next!=NULL) {
last=last->next;
}
last->next=new_node;
return;
}
void display(struct node *head) {
struct node *t=head;
while(t!=NULL) {
printf("%s",t->sc);
t=t->next;
}
}
void main() {
FILE *fp;
fp=fopen("C:\\Users\\Jefferson Warie\\Desktop\\input.txt","r");
if(fp==NULL) {
printf("File could not be opened.");
}
struct node *num1h;
num1h=NULL;
int i=0,j;
char arr[100][30];
while(!feof(fp)) {
fgets(arr[i],31,fp);
i++;
}
for(i=0; i<2; i++) {
strcpy(ch,arr[i]);
for(j=0; ch[j]!='\0'; j++) {
if(i==0) {
insert(&num1h,j);
}
}
}
printf("First linked list: ");
display(num1h);
}

Receive SIGSEGV in _IO_vfscanf_internal()

My program will compile and run normally, however, when I run the program through GDB, I receive a SIGSEGV, Segmentation fault
(0x0000003ec945352f in _IO_vfscanf_internal () from /lib64/libc.so.6)
after the fscanf in my code fills a node of a linked list. What causes the segmentation fault in GDB but not when I run my program?
(gdb) s
90 fscanf(fp,"%s %s %d %d", newNode->record_->first_name_, newNode->record_->last_name_, &newNode->record_->student_id_, &newNode->record_->student_age_);
(gdb) s
Program received signal SIGSEGV, Segmentation fault.
0x0000003ec945352f in _IO_vfscanf_internal () from /lib64/libc.so.6
#include <stdio.h>
#include <stdlib.h>
struct student_record_node
{
struct student_record* record_;
struct student_record_node* next_;
};
struct student_record
{
int student_id_;
int student_age_;
char first_name_[21];
char last_name_[21];
};
void parseFile();
struct student_record_node* student_record_allocate();
void appendNode(struct student_record_node* head, struct student_record_node* newNode);
void printNode(struct student_record_node* node);
void student_record_node_deallocate(struct student_record_node* node);
void printNodeList(struct student_record_node* head);
void swap(struct student_record_node** node1, struct student_record_node** node2);
void sortByAge(struct student_record_node** recordsHead);
void sortById(struct student_record_node** recordsHead);
void freeNodeList(struct student_record_node* head);
void student_record_node_deallocate(struct student_record_node* node);
int main(int argc, char* argv[])
{
struct student_record_node* node = student_record_allocate();
struct student_record_node** head = &node;
parseFile(argv[1], head);
printf("Before sorting...\n");
printNodeList(*head);
sortByAge(head);
printf("Sorting by age...\n");
printNodeList(*head);
sortById(head);
printf("Sorting by id...\n");
printNodeList(*head);
freeNodeList(*head);
}
struct student_record_node* student_record_allocate()
{
struct student_record_node* newNode;
newNode = calloc(1, sizeof(struct student_record_node));
if (newNode == NULL)
{
printf("No memory allocated for newNode");
exit(1);
}
newNode->record_ = calloc(1, sizeof(struct student_record));
if (newNode->record_ == NULL)
{
printf("No memory allocated for record_");
exit(1);
}
newNode->next_ = NULL;
return newNode;
}
void parseFile(char* filename, struct student_record_node** head)
{
int i = 0;
struct student_record_node* newNode = *head;
FILE* fp;
fp = fopen(filename,"r");
if (fp == NULL)
{
printf("Could not read file\n");
exit(1);
}
while(1)
{
if(newNode != *head)
{
newNode = student_record_allocate();
appendNode(*head, newNode);
}
fscanf(fp,"%s %s %d %d", newNode->record_->first_name_, newNode->record_->last_name_, &newNode->record_->student_id_, &newNode->record_->student_age_);
if(newNode == *head)
{
newNode = NULL;
}
if(feof(fp))
{
break;
}
}
fclose(fp);
}
void appendNode(struct student_record_node* head, struct student_record_node* newNode)
{
int i = 1;
struct student_record_node* current = head;
while (i)
{
if (current->next_ == NULL)
{
current->next_ = newNode;
i = 0;
}
current = current->next_;
}
}
void printNode(struct student_record_node* node)
{
printf("struct student_record_node:\n");
printf("\tStudent first name: %s\n", node->record_->first_name_);
printf("\tStudent last name: %s\n", node->record_->last_name_);
printf("\tStudent id: %d\n", node->record_->student_id_);
printf("\tStudent age: %d\n", node->record_->student_age_);
}
void printNodeList(struct student_record_node* head)
{
struct student_record_node* current = head;
while (current->next_ != NULL)
{
printNode(current);
current = current->next_;
}
printf("\n");
}
void swap(struct student_record_node** node1, struct student_record_node** node2)
{
struct student_record* newNode;
struct student_record_node* big = *node2;
struct student_record_node* small = *node1;
newNode = big->record_;
big->record_ = small->record_;
small->record_ = newNode;
}
void sortByAge(struct student_record_node** recordsHead)
{
int i,j;
struct student_record_node* current = *recordsHead;
struct student_record_node* next = *recordsHead;
while (current->next_->next_ != NULL)
{
next = current;
while (next->next_->next_ != NULL)
{
if (next->next_->record_->student_age_ <= next->record_->student_age_)
{
swap(&next->next_, &next );
}
next = next->next_;
}
current = current->next_;
}
}
void sortById(struct student_record_node** recordsHead)
{
int i = 0;
struct student_record_node* current = *recordsHead;
struct student_record_node* beginning = *recordsHead;
struct student_record_node* next = *recordsHead;
while (current->next_->next_ != NULL)
{
next = beginning;
while(next->next_->next_ !=NULL)
{
if (next->next_->record_->student_id_ <= next->record_->student_id_)
{
swap(&next->next_, &next);
}
next = next->next_;
}
current = current->next_;
}
}
void student_record_node_deallocate(struct student_record_node* node)
{
struct student_record_node* tmp;
tmp = node;
free(tmp->record_);
free(tmp);
}
void freeNodeList(struct student_record_node* head)
{
while (head != NULL)
{
student_record_node_deallocate(head);
head = head->next_;
}
}

segmenation fault error in my linkedList -C

I put together a few pieces of code to make a linked list that adds to head(Has a special function) and in the middle(also special function).
my problem is, i need to provide the program with numbers and insert them as nodes in my LINKEDLIST. However, my display function(to display the tree of nodes) gives back segmentation fault and so does just taking values in without any display function.
I'm fairly new to malloc so i suspect the problem is there?
Thanks
#include<stdio.h>
#include<stdlib.h>
/*LINKEDLIST STRUCT*/
struct node {
int data;
struct node *next;
};
/*Inserting head-Node*/
struct node *insert_head(struct node *head, int number)
{
struct node *temp;
temp = malloc(sizeof(struct node));
if(temp == NULL)
{
printf("Not enough memory\n");
exit(1);
}
temp->data = number;
temp->next = head;
head = temp;
return head;
}
/*Inserting inside a list*/
void after_me(struct node *me, int number)
{
struct node *temp;
temp = malloc(sizeof(struct node));
if(temp == NULL)
{
printf("Not enough memory\n");
exit(1);
}
temp->data = number;
temp->next = me->next;
me->next = temp;
}
/*PRINTING LIST*/
void display(struct node *head)
{
struct node *moving_ptr = head;
while(moving_ptr != NULL)
{
printf("%d-->",moving_ptr->data);
moving_ptr = moving_ptr->next;
}
}
int main()
{
int index;
struct node *head;
struct node *previous_node;
scanf("%d", &index);
while(index > 0)
{
/*allocating in List */
if(head == NULL)
head = insert_head(head,index);
else
if((head != NULL) && (index <= (head->data)))
{
struct node *temp;
head->next = temp;
temp->next = head;/*TRY INSERT HEAD FUNC.*/
}
else
if((head != NULL) && (index > (head->data)))
{
previous_node->data = index-1;
after_me(previous_node,index);
}
scanf("%d", &index);
}
display(head);
}
I suggest as follows.
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
//aggregated into one place
struct node *new_node(int number){
struct node *temp;
if(NULL == (temp = malloc(sizeof(*temp)))){
printf("\nNot enough memory\n");
exit(1);
}
temp->data = number;
temp->next = NULL;
return temp;
}
struct node *insert_head(struct node *head, int number) {
struct node *temp = new_node(number);
temp->next = head;
return temp;
}
void after_me(struct node *me, int number){
struct node *temp = new_node(number);
temp->next = me->next;
me->next = temp;
}
void display(struct node *head){
struct node *moving_ptr = head;
while(moving_ptr != NULL){
printf("%d", moving_ptr->data);
if(moving_ptr = moving_ptr->next)
printf("-->");
}
putchar('\n');
}
struct node *insert(struct node *me, int number){
if(me){
if(number <= me->data){
me = insert_head(me, number);
} else {
me->next = insert(me->next, number);
}
} else {
me = new_node(number);
}
return me;
}
void release(struct node *list){//Of course, you will be able to replace a simple loop(e.g while-loop).
if(list){
release(list->next);
free(list);
}
}
int main(void){
struct node *head = NULL;
int index;
while(1==scanf("%d", &index) && index > 0){
head = insert(head, index);
}
display(head);
release(head);
return 0;
}

Linked list add() method in C

Where is error the following code?
addNode() function is not run, neither is the traverse() function.
Last data is not shown.
#include <stdio.h>
#include <stdlib.h>
struct isimler{
char isim[10];
struct isimler *next;
};
typedef struct isimler node;
node *head;
void createList(){
int k, n;
node *po;
printf("Eleman Sayisi: "); scanf("%d", &n);
for(k = 0; k<n; k++){
if(k == 0){
head = (node *) malloc(sizeof(node));
po = head;
}else{
po->next = (node *) malloc(sizeof(node));
po = po->next;
}
printf("Isim Girin: "); scanf("%s",po->isim);
}
po->next = NULL;
}
void addNode(){
node *po, *newNode;
po = head;
while(po != NULL){
po = po->next;
}
po = (node *) malloc(sizeof(node));
printf("Isim Girin: "); scanf("%s", po->isim);
po->next = NULL;
}
void traverseList(){
node *po;
int i=0;
po = head;
while(po != NULL){
printf("%d.\t%s\n",i,po->isim);
po = po->next;
i++;
}
}
int main(){
createList();
traverseList();
addNode();
traverseList();
return 1903;
}
Your current addNode() method creates a new node but it doesn't add it to your linked list.
You need to modify your addNode() method like so:
void addNode(){
node *po, *newNode;
po = head;
while(po->next != NULL) { // change this so you don't lose the end of the list
po = po->next; // po is now pointing to the last node in the list
}
newNode = (node *) malloc(sizeof(node)); // change this to newNode
printf("Isim Girin: "); scanf("%s", newNode->isim);
po->next = newNode; // add the new node here, don't set it to NULL
newNode->next = NULL;
}
You can have look this code and get to know where exactly you are having problem
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
struct test_struct
{
int val;
struct test_struct *next;
};
struct test_struct *head = NULL;
struct test_struct *curr = NULL;
struct test_struct* create_list(int val)
{
printf("\n creating list with headnode as [%d]\n",val);
struct test_struct *ptr = (struct test_struct*)malloc(sizeof(struct test_struct));
if(NULL == ptr)
{
printf("\n Node creation failed \n");
return NULL;
}
ptr->val = val;
ptr->next = NULL;
head = curr = ptr;
return ptr;
}
struct test_struct* add_to_list(int val, bool add_to_end)
{
if(NULL == head)
{
return (create_list(val));
}
if(add_to_end)
printf("\n Adding node to end of list with value [%d]\n",val);
else
printf("\n Adding node to beginning of list with value [%d]\n",val);
struct test_struct *ptr = (struct test_struct*)malloc(sizeof(struct test_struct));
if(NULL == ptr)
{
printf("\n Node creation failed \n");
return NULL;
}
ptr->val = val;
ptr->next = NULL;
if(add_to_end)
{
curr->next = ptr;
curr = ptr;
}
else
{
ptr->next = head;
head = ptr;
}
return ptr;
}
struct test_struct* search_in_list(int val, struct test_struct **prev)
{
struct test_struct *ptr = head;
struct test_struct *tmp = NULL;
bool found = false;
printf("\n Searching the list for value [%d] \n",val);
while(ptr != NULL)
{
if(ptr->val == val)
{
found = true;
break;
}
else
{
tmp = ptr;
ptr = ptr->next;
}
}
if(true == found)
{
if(prev)
*prev = tmp;
return ptr;
}
else
{
return NULL;
}
}
int delete_from_list(int val)
{
struct test_struct *prev = NULL;
struct test_struct *del = NULL;
printf("\n Deleting value [%d] from list\n",val);
del = search_in_list(val,&prev);
if(del == NULL)
{
return -1;
}
else
{
if(prev != NULL)
prev->next = del->next;
if(del == curr)
{
curr = prev;
}
else if(del == head)
{
head = del->next;
}
}
free(del);
del = NULL;
return 0;
}
void print_list(void)
{
struct test_struct *ptr = head;
printf("\n -------Printing list Start------- \n");
while(ptr != NULL)
{
printf("\n [%d] \n",ptr->val);
ptr = ptr->next;
}
printf("\n -------Printing list End------- \n");
return;
}
int main(void)
{
int i = 0, ret = 0;
struct test_struct *ptr = NULL;
print_list();
for(i = 5; i<10; i++)
add_to_list(i,true);
print_list();
for(i = 4; i>0; i--)
add_to_list(i,false);
print_list();
for(i = 1; i<10; i += 4)
{
ptr = search_in_list(i, NULL);
if(NULL == ptr)
{
printf("\n Search [val = %d] failed, no such element found\n",i);
}
else
{
printf("\n Search passed [val = %d]\n",ptr->val);
}
print_list();
ret = delete_from_list(i);
if(ret != 0)
{
printf("\n delete [val = %d] failed, no such element found\n",i);
}
else
{
printf("\n delete [val = %d] passed \n",i);
}
print_list();
}
return 0;
}

Resources