Please help values wont save once added into the list and nothing is printed as a result
#include <stdio.h>
#include <stdlib.h>
struct node{
char first[30];
char last[30];
char address[100];
char postal[6];
char number[10];
struct node* next;
};
typedef struct node node;
void print(node* root);
node* add(node* root);
void addinfo(node* root);
int main(){
node* root=NULL;
root=add(root);
print(root);
return 0;
}
Its supposed to add a new node at the end of the list then add values
node* add(node* root){
if(root==NULL){
root=(node*) malloc(sizeof(node));
addinfo(root);
root->next=NULL;
return root;
}
node* temp=root;
while(temp!=NULL){
temp=temp->next;
}
temp=(node*)malloc(sizeof(node));
addinfo(temp);
temp->next=NULL;
return root;
}
void print(node* root){
node* temp=root;
while(temp!=NULL){
printf("First Name: %s\n",temp->first);
printf("Last Name:%s\n",temp->last);
printf("Address:%s\n",temp->address);
printf("Postal%s\n",temp->postal);
printf("Phone Number:%s\n",temp->number);
temp=temp->next;
}
}
If I print in the function, the values print normally but once this functions ends all the values are gone.
void addinfo(node* root){
node* temp=root;
while(temp!=NULL){
temp=temp->next;
}
temp=malloc(sizeof(node));
printf("Please enter a name:");
gets(temp->first);
printf("Please enter a last name:");
gets(temp->last);
printf("Please enter an address:");
gets(temp->address);
printf("Please enter a postal code:");
gets(temp->postal);
printf("Please enter a phone number:");
gets(temp->number);
}
The simplest way of implementing what you want is keeping a pointer to the last item of a list:
typedef struct list {
node *first;
node *last;
} list;
Then you initialize a list with
list alist = { NULL, NULL };
and add items as follows:
void addNewNode(list *plist, node *pnode)
{
pnode->next = NULL;
if( plist->first == NULL)
plist->first = pnode;
else
plist->last->next = pnode;
plist->last = pnode;
}
fill the list:
while(there_is_something_to_read())
{
node *newnode = malloc(sizeof(node));
addInfo(newnode);
addNewNode(&alist, newnode);
}
note however, addInfo() should do just what its name says: add info to the node; no list manipulation:
void addinfo(node* pnode){
printf("Please enter a name:");
gets(pnode->first);
// .........
printf("Please enter a phone number:");
gets(pnode->number);
}
print it:
node *pnode;
for(pnode = alist.first; pnode != NULL; pnode = pnode->next)
printNode(pnode);
with
void printNode(node *pnode)
{
printf( "first name: %s\n", pnode->first);
//...
printf( "phone: %s\n", pnode->number);
printf( "\n");
}
The problem is in this code:
void addinfo(node* root){
node* temp=root;
while(temp!=NULL){
temp=temp->next;
}
temp=malloc(sizeof(node));
You carefully traverse the entire list until temp is NULL (which could be achieved more swiftly by writing temp = NULL; and then you overwrite the NULL with newly allocated memory, but don't hook the new node into the list.
This function cannot be used on an empty list. It can be revised to work on a non-empty list:
void addinfo(node *root)
{
if (root == NULL)
return; // Report error?
node *temp = root;
while (temp->next != NULL)
temp = temp->next;
temp->next = malloc(sizeof(node));
if (temp->next == NULL)
return; // Report error?
temp = temp->next;
temp->next = NULL;
…other code as before…
}
Related
bellow there is a simple code for a binary search tree. It has 2 cases, the first one inserts values to the tree and the second one finds the preorder traversal of the tree.
My question has to do with the malloc function. In the first case we have this ptr = (struct node *)malloc(sizeof(struct node)); and lets say that the value that we want to insert is 50. I can see while debugging that ptr=50 and I can't understand how (struct node *)malloc(sizeof(struct node)) gives this result.
Also when we have struct node *ptr, *nodeptr, *parentptr as pointing variables to struct node inside the function and after that we have for example parentptr=NULL; this parentptr refers to the pointer *parentptr or its just a variable.
struct node
{
int data;
struct node* left;
struct node* right;
};
struct node* tree;
struct node*
insert(struct node*, int);
void
preorder(struct node*);
int
main()
{
int option, val;
struct node* ptr;
tree = NULL;
do {
printf("\n ******MAIN MENU******* \n");
printf("\n 1. Insert an element");
printf("\n 2. Preorder Traversal");
printf("\n 3. Exit");
printf("\n\n Enter your option : ");
scanf("%d", &option);
switch (option) {
case 1:
printf("\n Enter the value of the new node : ");
scanf("%d", &val);
tree = insert(tree, val);
break;
case 2:
printf("\n The elements of the tree are : \n");
preorder(tree);
break;
}
} while (option != 3);
getch();
return 0;
}
struct node*
insert(struct node* tree, int val)
{
struct node *ptr, *nodeptr, *parentptr;
ptr = (struct node*)malloc(sizeof(struct node));
ptr->data = val;
ptr->left = NULL;
ptr->right = NULL;
if (tree == NULL) {
tree = ptr;
tree->left = NULL;
tree->right = NULL;
} else {
nodeptr = tree;
parentptr = NULL;
while (nodeptr != NULL) {
parentptr = nodeptr;
if (val < nodeptr->data)
nodeptr = nodeptr->left;
else
nodeptr = nodeptr->right;
}
if (val < parentptr->data)
parentptr->left = ptr;
else
parentptr->right = ptr;
}
return tree;
}
void
preorder(struct node* tree)
{
if (tree != NULL) {
printf("%d\t", tree->data);
preorder(tree->left);
preorder(tree->right);
}
}
I was practicing a bit of linked list and I was trying to add elements into sorted doubly linked list. However when I call the the function to add the element in the list, instead of calling the function, program goes into an infinte loop. I have checked the the program does not enter the function adding print statement at start of function. Here's the whole program:
#include<stdio.h>
#include<stdlib.h>
struct node
{
int info;
struct node* next;
struct node* prev;
};
struct node* sortedInsert(struct node* head, int data)
{
printf("x" );
struct node* res=head;
struct node* ptr=(struct node*)malloc(sizeof(struct node));
ptr->info=data;
ptr->next=NULL;
ptr->prev=NULL;
printf("X");
if(head==NULL)
return ptr;
else if(ptr->info<=head->info)
{
ptr->next=head;
head->prev=NULL;
res=ptr;
return res;
}
else
{
while(head!=NULL)
{
if(head->info>=ptr->info)
{
ptr->prev=head->prev;
ptr->next=head;
head->prev=ptr;
return res;
}
}
}
}
struct node* push(struct node* head)
{
struct node* ptr=(struct node*)malloc(sizeof(struct node));
int n;
printf("Enter size: ");
scanf("%d",&n);
printf("Enter elements: ");
for(int i=0;i<n;i++)
{
if(head==NULL)
{
scanf("%d",&ptr->info);
ptr->next=NULL;
ptr->prev=NULL;
head=ptr;
}
else
{
struct node* temp=(struct node*)malloc(sizeof(struct node));
scanf("%d",&temp->info);
temp->next=NULL;
temp->prev=ptr;
ptr->next=temp;
ptr=temp;
}
}
return head;
}
void display(struct node* head)
{
struct node *res;
for(res=head;res!=NULL;res=res->next)
printf("%d\t",res->info);
printf("\n");
}
int main()
{
struct node* head1=NULL;
head1=push(head1);
display(head1);
int num;
printf("Enter number: ");
scanf("%d",&num);
printf("%d\n",num);
head1=sortedInsert(head1,num);
display(head1);
return 0;
}
Output is:
Enter size: 4
Enter elements: 1 2 4 5
1 2 4 5
Enter number: 3
3
It is because you are not incrementing the head to point next node in the while loop.
Also once you found the position in the list where new node to be inserted you need to make prev node point to new node
head->prev->next = ptr; other wise your list will break;
Your code should look like below.
struct node* sortedInsert(struct node* head, int data)
{
.......
.......
while(head!=NULL)
{
if(head->info>=ptr->info)
{
ptr->prev=head->prev;
ptr->next=head;
head->prev->next = ptr; // to make prev node to point new node
head->prev=ptr;
return res;
}
head=head->next; // Increment the head to point next node.
}
.......
}
Task is to create a linked list consisting of objects. User inputs data for each individual Node in the main and then the object is being passed to push, which creates the list.
The problem comes in the printList function, where the condition for a break is never met.
For some reason the line head = head->next doesn't do anything, as the address of next with every iteration remains the same.
typedef struct Node {
int a;
char asd[30];
struct Node *next;
}Node;
Node *head = NULL;
void push(Node**head, struct Node* object);
void printList(Node *head);
int main() {
struct Node {
int oA;
char oAsd[30];
struct Node *next;
};
struct Node *object = malloc(sizeof(struct Node));
int c = 0;
while (1) {
printf("This int will be stored in Node %d.\n", ++c);
scanf("%d", &object->oA);
getchar();
if (!object->oA) {
break;
}
printf("This string will be stored in Node %d.\n", c);
gets_s(object->oAsd, 30);
if (!(strcmp(object->oAsd, "\0"))) {
break;
}
push(&head, object);
}
printList(head);
return 0;
}
void push(Node ** head, struct Node* object)
{
Node *tmp = malloc(sizeof(Node));
tmp = object;
tmp->next = (*head);
(*head) = tmp;
}
void printList(Node *head) {
if (head == NULL) {
puts("No list exists.");
exit(9);
}
while (1) {
printf("-------------------------------\n");
printf("|Int: <%d> |||| String: <%s>.|\n", head->a, head->asd);
printf("-------------------------------\n");
if (head->next) {
printf("\n\n%p\n\n", head->next);
head = head->next;
}
else {
break;
}
}
}`
There are two major problems in your code:
You define struct Node both outside main and inside main
Here tmp = object; you copy the value of a pointer to another pointer but you really want to copy the value of a struct to another struct, i.e. *tmp = *object;.
Besides that - don't put head as a global variable.
So the code should be more like:
typedef struct Node {
int a;
char asd[30];
struct Node *next;
}Node;
void push(Node**head, struct Node* object);
void printList(Node *head);
int main() {
Node *head = NULL;
struct Node *object = malloc(sizeof(struct Node));
int c = 0;
while (1) {
printf("This int will be stored in Node %d.\n", ++c);
scanf("%d", &object->a);
getchar();
if (!object->a) {
break;
}
printf("This string will be stored in Node %d.\n", c);
gets_s(object->asd, 30);
if (!(strcmp(object->asd, "\0"))) {
break;
}
push(&head, object);
}
printList(head);
return 0;
}
void push(Node ** head, struct Node* object)
{
Node *tmp = malloc(sizeof(Node));
*tmp = *object; // Copy the struct
tmp->next = (*head);
(*head) = tmp;
}
void printList(Node *head) {
if (head == NULL) {
puts("No list exists.");
exit(9);
}
while (1) {
printf("-------------------------------\n");
printf("|Int: <%d> |||| String: <%s>.|\n", head->a, head->asd);
printf("-------------------------------\n");
if (head->next) {
printf("\n\n%p\n\n", head->next);
head = head->next;
}
else {
break;
}
}
}
struct node{
char name[50];
double grade;
struct node* next;
};
void append(struct node* root){
int n;
printf("Enter the number of students: ");
scanf("%d",&n);
while(n !=0){
struct node* temp;
temp=(struct node*)malloc(sizeof(struct node));
printf("\nEnter the name of the student: ");
scanf("%s",&temp->name);
printf("\nEnter the grade for the student named %s: ",temp->name);
scanf("%f",&temp->grade);
temp->next=NULL;
if(root==NULL){
root=temp;
}else{
struct node* iterate=root;
while(iterate->next != NULL){
iterate=iterate->next;
}
iterate->next=temp;
}
n--;
}
}
int listLength(struct node* root){
struct node* temp = root;
int counter=0;
while(temp !=NULL){
counter++;
temp=temp->next;
}
return counter;
}
int main()
{
struct node* root = NULL;
append(&root);
//printList(&root);
printf("Node length: %d",listLength(&root));
return 0;
}
This is what I have so far as I'm starting out with linked lists. I tried to make it so I can append to multiple linked lists with the function. So I'd just create a different root pointer in main and call the append function with it as a parameter to add nodes.
This seems to work, however, it adds an extra empty node at the beginning of the list. This node doesn't contain any data. So for example, if I add 4 students to the list the nodeLength function would return 5.
Change this:
void append(struct node* root)
to this:
void append(struct node** root)
so that you make the changes last even when append() terminates.
Of course then you will have to use *root instead of root inside the body of that function.
PS: Do I cast the result of malloc? No.
struct node{
char name[50];
double grade;
struct node* next;
};
struct node * append(struct node* root){
int n;
printf("Enter the number of students: ");
scanf("%d",&n);
while(n !=0){
struct node* temp;
temp=(struct node*)malloc(sizeof(struct node));
printf("\nEnter the name of the student: ");
scanf("%s",&temp->name);
printf("\nEnter the grade for the student named %s: ",temp->name);
scanf("%f",&temp->grade);
temp->next=NULL;
if(root==NULL){
root=temp;
}else{
struct node* iterate=root;
while(iterate->next != NULL){
iterate=iterate->next;
}
iterate->next=temp;
root=iterate;
}
n--;
}
return root; }
int nodeLength(struct node* root){
struct node* temp = root;
int counter=0;
while(temp !=NULL){
counter++;
temp=temp->next;
}
return counter;
}
int main()
{
struct node* root = NULL;
root= append(root);
//printList(&root);
printf("Node length: %d",nodeLength(root));
return 0;
}
Check this code to understand a bit. Will explain more.
And don't cast the return type of malloc.
Here what you are doing will work fine for if you correctly changed the parameter to struct node** but yes it can be done more easily like this(example shown above). It's natural and more intuitive rather than using double pointer.
I have written a linked list program which stores data member as void *.
while trying to store annd print using scanf/printf functions, I am getting segmentation fault.
node definition -->
typedef struct node {
struct node *next;
void *data;
}node;
main function -->
head=(node *)malloc(sizeof(node));
if (head==NULL){
printf("error in allocation of memory\n");
exit(EXIT_FAILURE);
}
tail=(node*)create(head);
create function -->
void *create(node *current)
{
int user_choice;
while(current){
printf("\nEnter the data:");
scanf("%s",current->data);
printf("stored at %p\n",(void*)current->data);
printf("%s",(char*)current->data);
printf("\nType '1' to continue, '0' to exit:\n");
scanf("%d",&user_choice);
if(user_choice == 1){
current->next=(node*)malloc(sizeof(node));
current=current->next;
}
else{
current->next=NULL;
}
}
return current;
}
can anyone tell what is the correct argument for scanf & prinf should be..?
working code after incorporating points given in answers...
void *create(node *current)
{
node *temp;
int user_choice;
while(current){
printf("\nEnter the data:");
current->data=(char*)malloc(10*sizeof(char));
scanf("%s",current->data);
printf("stored at %p\n",(void*)current->data);
printf("%s",(char*)current->data);
printf("\nType '1' to continue, '0' to exit:\n");
scanf("%d",&user_choice);
if(user_choice == 1){
current->next=(node*)malloc(sizeof(node));
}
else{
current->next=NULL;
temp=current;
}
current=current->next;
}
return temp;
}
In your code,
scanf("%s",current->data);
is attempt to make use of an unitialized pointer, it invokes undefined behavior.
You need to follow either of bellow approach,
make the pointer point to valid chunk of memory (using malloc() and family for dynamic allocation, for example)
use an array.
You should first initialize data member of structure because
current->data = malloc("passes size here");
For putting data you have to typecast first this data because void is not storage type. void pointer can be used to point to any data type.
Like
*(char *)(current->data) = 1;
As others have said:
scanf("%s",current->data);
Is undefined in C. current->data needs to be pointing somewhere before you can store anything in it.
You should instead:
Accept input from scanf.
Store in temporary buffer.
Insert into linked list
print out whole linked list at the end
free() linked list at the end.
I also feel that your current void *create function is doing too much, and it would be easier to split up your code into different functions, just to make it easier to handle all the pointer operations, inserting etc.
To demonstrate these points, I wrote some code a while ago which does these things, and has been modified to help you with your code. It is not the best code, but it does use these points that will help you with your code.
Here it is:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSTRLEN 100
typedef struct node {
void *data;
struct node *next;
} node_t;
typedef struct {
node_t *head;
node_t *foot;
} list_t;
list_t *create_list(void);
node_t *generate_node(void);
list_t *insert_node(list_t *list, char *data);
void print_list(list_t *list);
void free_list(list_t *list);
int
main(int argc, char *argv[]) {
list_t *list;
char data[MAXSTRLEN];
int user_choice;
list = create_list();
while (1) {
printf("Enter the data: ");
scanf("%s", data);
printf("\nType '1' to continue, '0' to exit:\n");
if (scanf("%d",&user_choice) != 1) {
printf("Invalid input\n");
exit(EXIT_FAILURE);
}
if (user_choice == 1) {
list = insert_node(list, data);
} else {
list = insert_node(list, data);
break;
}
}
print_list(list);
free_list(list);
list = NULL;
return 0;
}
/* inserting at foot, you can insert at the head if you wish. */
list_t
*insert_node(list_t *list, char *data) {
node_t *newnode = generate_node();
newnode->data = malloc(strlen(data)+1);
strcpy(newnode->data, data);
newnode->next = NULL;
if (list->foot == NULL) {
list->head = newnode;
list->foot = newnode;
} else {
list->foot->next = newnode;
list->foot = newnode;
}
return list;
}
node_t
*generate_node(void) {
node_t *new = malloc(sizeof(*new));
new->data = NULL;
return new;
}
void
print_list(list_t *list) {
node_t *curr = list->head;
printf("\nlinked list data:\n");
while(curr != NULL) {
printf("%s\n", (char*)curr->data);
curr = curr->next;
}
}
list_t
*create_list(void) {
list_t *list = malloc(sizeof(*list));
if (list == NULL) {
fprintf(stderr, "%s\n", "Error allocating memory");
exit(EXIT_FAILURE);
}
list->head = NULL;
list->foot = NULL;
return list;
}
void
free_list(list_t *list) {
node_t *curr, *prev;
curr = list->head;
while (curr) {
prev = curr;
curr = curr->next;
free(prev);
}
free(list);
}
UPDATE:
Also note how I allocated memory for newnode->data?
Like this:
newnode->data = malloc(strlen(data)+1); //using buffer from scanf
This now means I can store data in this pointer, your current->data will need to do something similar.
working code-->
void *create(node *current)
{
node *temp;
int user_choice;
while(current){
printf("\nEnter the data:");
current->data=(char*)malloc(10*sizeof(char));
scanf("%s",current->data);
printf("stored at %p\n",(void*)current->data);
printf("%s",(char*)current->data);
printf("\nType '1' to continue, '0' to exit:\n");
scanf("%d",&user_choice);
if(user_choice == 1){
current->next=(node*)malloc(sizeof(node));
}
else{
current->next=NULL;
temp=current;
}
current=current->next;
}
return temp;
}
Please try with this
void *create(node *current)
{
int user_choice;
while(true){
if(current == NULL) {
current = (node *)malloc(sizeof(node));
current->data = NULL;
current->next = NULL;
}
printf("\nEnter the data:");
scanf("%s",current->data);
printf("stored at %p\n", (void *)current->data);
printf("%s",current->data);
//printf("%s",(char*)current->data);
printf("\nType '1' to continue, '0' to exit:\n");
scanf("%d",&user_choice);
if(user_choice == 1){
current->next=(node*)malloc(sizeof(node));
current=current->next;
}
else{
current->next=NULL;
tail = current;
current=current->next;
break;
}
}
return current;
}
Note: The element has to be initialized (ie; it has to be alloted with some memory) before we are trying to make use of it.