Linked string list in c - c

I'm trying this simple code which asks a user for string input. As it receives an input it then tries to copy each element of the string into different location in a linked list. Everything works just fine (I think) but when i print the linked list, the screen doesnt show any out put. Any idea why is this happening?
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct node {
char data;
struct node* next;
};
struct node* head = NULL;
void insert(char);
void print();
void main() {
char str1[20];
int i;
printf("Enter the string\n");
fgets(str1,20,stdin);
int len = strlen(str1);
printf("%d\n",len);
for(i=0;i<len;i++) {
insert(str1[i]);
}
print();
}
void insert(char str) {
struct node* temp = (struct node*)malloc(sizeof(struct node));
struct node* temp1 = head;
while(temp1!=NULL) {
temp1 = temp1->next;
}
temp->data = str;
temp1 = temp;
}
void print() {
struct node *temp;
temp = head;
while(temp!=NULL) {
printf("%c ",temp->data);
temp = temp->next;
}
}

You never set head to anything, it will always be NULL. So, you're not creating a list, but a group of unlinked floating nodes.
On another note, don't cast the result of malloc
On yet another note, no need to go through the entire list for every insert - you can keep a tail pointer along with the head, so adding to the end is done without a loop.

void insert(char str) {
struct node* temp = (struct node*)malloc(sizeof(struct node));
temp->data = str;
temp->next = NULL;
if(head){//head != NULL
struct node* temp1 = head;
while(temp1->next != NULL) {//search last element
temp1 = temp1->next;
}
temp1->next = temp;//insert new node
} else {
head = temp;//if head == NULL then replace with new node
}
}

Related

C programming - Reverse a linked link by iterative method

I am trying to reverse a linked by iterative method. Magically, after watching tutorial and trying to recode myself, the program works successfully. However, when I review the code, I hit a question: in line 23, why we must use temp1->next instead of temp1? When traversing to the end of the linked list, which case we use the condition (the node != NULL)? In which case we use (the link of the node ! = NULL)? I fully appreciate it if anyone can enlighten me.
#include <stdio.h>
#include <stdlib.h>
struct Node
{
int data;
struct Node* next;
};
struct Node* Insert(struct Node* head, int data)
{
struct Node* temp = (struct Node*) malloc(sizeof(struct Node));
temp->data = data;
temp->next = NULL;
//If the list is empty
if (head == NULL)
{
head = temp;
}
else //The list is not empty
{
struct Node* temp1 = head;
while (temp1->next != NULL)
{
temp1 = temp1->next;
}
temp1->next = temp;
}
return head;
}
void Print(struct Node* head)
{
struct Node* temp = head;
while (temp != NULL)
{
printf("%d ", temp->data);
temp = temp->next;
}
printf("\n");
}
struct Node* Reverse(struct Node* head)
{
struct Node* *prev, *current, *next;
current = head;
prev = NULL;
while (current != NULL)
{
next = current->next;
current->next = prev;
prev = current;
current = next;
}
head = prev;
return head;
}
int main()
{
struct Node* head = NULL;
printf("Enter the length of the linked list you want to create: ");
int length;
scanf("%d", &length);
printf("Enter the value you want to input: ");
int i;
for (i = 0; i < length; i++)
{
int x;
scanf("%d", &x);
head = Insert(head, x);
}
printf("Given linked list\n");
Print(head);
head = Reverse(head);
printf("\nReversed linked list \n");
Print(head);
return 0;
}
In that case, inside the while condition, on line 23, you can notice that the program is using temp1 = temp1->next, if you change the condition to temp1 != NULL when it reaches the last element of linked list it'll collect trash from memory or even result in an error, because NULL don't have a next position.
So, you use temp1 != NULL if you are accessing the data inside the list and temp1->next != NULL if you are manipulating the next positions of the linked list.
Because temp1->next at the end of the linked list is NULL, however, the last node has data, if you use temp1 == NULL you would say that the last node is NULL, which is not the case. So you want to end the loop when the "pointer to the next node" is NULL, not when the next node is NULL.

Linked List elements not getting displayed

This is my program in C which always inserts into a linked list at the end. But when I try to print the list elements, nothing is displayed. Here is the code :
#include<stdio.h>
#include<stdlib.h>
struct Node
{
int data;
struct Node *next;
};
void insert(struct Node *, int);
int main(void)
{
struct Node *head = NULL, *current;
int n, i, x, data;
scanf("%d", &n);
for(i = 0; i < n; i++)
{
scanf("%d", &data);
insert(head, data);
}
current = head;
while(current != NULL)
{
printf("%d ", current->data);
current = current->next;
}
}
void insert(struct Node *head, int data)
{
struct Node *newnode, *current = head;
newnode = (struct Node *)malloc(sizeof(struct Node));
newnode->data = data;
newnode->next = NULL;
if(head == NULL)
{
head = newnode;
}
else
{
while(current->next != NULL)
{
current = current->next;
}
current->next = newnode;
}
}
I cannot understand what might be the issue. Please help.
Your insert cannot modify head. Change it to
void insert(struct Node **head, int data)
and change it by
*head = newnode;
and call it like this
insert(&head, data);
Here, while you are passing the head pointer to your insert() function, it is not being updated in your main() function.
So, either declare your head pointer as global or return your head pointer and update it in your main() function.
In the below code I had taken the head pointer as global and removed the head pointer as your parameter from the insert() function.
Here is the code :-
#include<stdio.h>
#include<stdlib.h>
struct Node
{
int data;
struct Node *next;
};
struct Node *head=NULL;
void insert(int);
int main(void)
{
struct Node *current;
int n, i, x, data;
clrscr();
scanf("%d", &n);
for(i = 0; i < n; i++)
{
scanf("%d", &data);
insert(data);
}
current = head;
while(current != NULL)
{
printf("%d \n", current->data);
current = current->next;
}
getch();
return 0;
}
void insert(int data)
{
struct Node *newnode, *current = head;
newnode = (struct Node *)malloc(sizeof(struct Node));
newnode->data = data;
newnode->next = NULL;
if(head == NULL)
{
head = newnode;
}
else
{
while(current->next != NULL)
{
current = current->next;
}
current->next = newnode;
}
}
You need to pass the reference of the head pointer, then only the changes made to it will be visible.
You must declare your function like
void insert(struct Node **, int);
and also call it like
insert(&head, data);
also, make changes to function definition
void insert(struct Node **head, int data)
{
struct Node *newnode, *current = *head;
newnode = (struct Node *)malloc(sizeof(struct Node));
newnode->data = data;
newnode->next = NULL;
if(*head == NULL)
{
*head = newnode;
}
else
{
while(current->next != NULL)
{
current = current->next;
}
current->next = newnode;
}
}
You need to pass the head by reference as you are making changes to it that should be visible.
insert(head, data);
should become
insert(&head, data);
Also the function signature will change.
void insert(struct Node *head, int data)
should become
void insert(struct Node **head, int data)
Also make appropriate changes in the function.
Like,
current = *head;
Because you are passing the pointer by value. The function operates on a copy of the pointer, and never modifies the original.
Either pass a pointer to the pointer (i.e. a struct head **), or instead have the function return the pointer.
You can try running the following code which will give the output as null
printf("%s",head);
while(current != NULL)
{
printf("%d", current->data);
current = current->next;
}

Linked List C: add node to beginning, unexpected '0' value

I am trying to add a new node to the end of a linked list, I am able to add something, but when I print it out the node has a value of '0'. I thought this might be happening because I may have neglected to initialise a variable somewhere, or forgot to allocate memory said variable. but I can't get it to work.
Here is my source code:
my Linked List/struct:
#include<stdio.h>
typedef char DATA;
struct Node {
DATA d;
struct Node *next;
};
my printList function:
void printList(struct Node **head) {
struct Node *newNode = malloc(sizeof(struct Node));
struct Node *temp;
temp = *head;
printf("Linked list:");
while (temp->next != NULL) {
printf( " \n %d ", temp->d);
temp = temp->next;
}
printf("\n");
}
my insertNodeAtEnd to end function:
// inset data at end
void insertNodeAtEnd(struct Node *head) {
struct Node *newNode = malloc(sizeof(struct Node));
struct Node *currentNode, *temp;
temp = newNode;
currentNode = newNode;
printf("Enter a Node to insert at the end of the list \n");
scanf("%s", &newNode->d);
newNode->next = NULL;
if (head == NULL) {
head = newNode;
currentNode = newNode;
} else {
temp = head;
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = newNode;
}
}
and my main():
int main() {
struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
struct Node *head = newNode;
struct Node *temp = newNode;
head->d = 1;
int i = 0;
printf("Enter 3 numbers");
for (i = 0; i < 3; i++) {
struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
scanf("%d", &temp->d);
temp->next = newNode;
temp = temp->next;
}
insertNodeAtEnd(head);
printList(&head);
return 0;
sorry for any messy code, I'm still reasonably new at this
Well, you have a couple of mistakes. Firstly, you need to add
temp->next = NULL;
before line insertNodeAtEnd(head);. The reason your code might work without this line is probably because your compiler initializes the pointer to NULL by default. For example in GCC you program is crashing without that line.Second problem is that you are defyning DATA type as a char, but reading it as int. It may cause crashing your application if processor working with big-engian addresses. You should change it to
typedef int DATA;
and also change
scanf("%s", &newNode->d);
to
scanf("%d", &newNode->d);
After that, change
while(temp->next!=NULL)
to
while(temp!=NULL)
because otherwise you are missing the last element. Then, you need to reorder a loop a little bit. This is the full working code with all fixes:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
typedef int DATA;
struct Node
{
DATA d;
struct Node *next;
};
void printList(struct Node **head)
{
struct Node *newNode;
struct Node *temp;
temp = *head;
printf("Linked list:");
while(temp!=NULL)
{
printf( " \n %d ", temp->d);
temp = temp->next;
}
printf("\n");
}
// inset data at end
void insertNodeAtEnd(struct Node **headPointer)
{
struct Node *head = *headPointer;
struct Node *newNode = malloc(sizeof(struct Node));
struct Node *currentNode, *temp;
temp = newNode;
currentNode = newNode;
printf("Enter a Node to insert at the end of the list \n");
scanf("%d", &newNode->d);
newNode->next = NULL;
if(head == NULL)
{
head = newNode;
currentNode = newNode;
}
else
{
temp = head;
while(temp->next!= NULL)
{
temp = temp->next;
}
temp->next = newNode;
}
*headPointer = head;
}
int main()
{
struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
struct Node *head = newNode;
struct Node *temp = newNode;
head->d = 1;
int i = 0;
printf("Enter 3 numbers: ");
for(i = 0; i < 3; i++)
{
if(i){
struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
temp->next = newNode;
temp = temp->next;
scanf("%d", &temp->d);
}else{
scanf("%d", &temp->d);
}
}
temp->next = NULL;
insertNodeAtEnd(&head);
printList(&head);
return 0;
}
UPDATE
I added a two more fixes. as #BLUEPIXY pointed out, there are a few more OP's mistakes. I've already spotted them, but I didn't fix it because they were not essential to what causes OP's problem. But, anyway, the mistakes are following:
Firstly, if the list is empty, function insertNodeAtEnd will not update pointer to the list because you are passing pointer to head of the list instead of pointer of a pointer to the head. It can be fixed by adding ** to the function argument type.
Secondly, you don't need to allocate memory while printing a list. You obviously just copied the code to each function, even to functions which doesn't require inserting nodes (like printList).
The above script is updated script including these two fixes.

Doubly Linked List Error

So, I'm trying to do operations in a doubly linked list, and I tried applying the logic of deletion but it's showing some sort of void error. Please tell me what's wrong in this code.
The error message is written alongside the line of code.
Function to get new node:
void getnewnode(int x)
{
struct node* temp = (struct node*)malloc(sizeof(struct node*));
temp->data = x;
temp->next = NULL;
temp->prev = NULL;
}
Insert function:
void insertatbeg(int x)
{
struct node* newnode=getnewnode(x); /* void value not ignored as it ought to be. */
if(head==NULL)
{
head = newnode;
}
else
{
head->prev = newnode;
newnode->next = head;
head = newnode;
}
}
Delete(nth node) function:
void delete(int n)
{
struct node* temp1=head;
int i;
if(temp1 == NULL)
return;
for(i = 0; i < n-2; i++)
{
temp1 = temp1->next;
}
struct node* temp2 = temp1->next;
(temp2->next)->prev = temp1;
temp1->next = temp2->next;
free(temp2);
}
Here is the main function:
struct node /* List called node */
{
struct node* next;
int data;
struct node* prev;
};
struct node* head;
void insertatbeg(int x);
void delete(int n);
int main()
{
int x;
head = NULL;
insertatbeg(x);
insertatbeg(x);
insertatbeg(x);
delete(2);
}
Looks to me your problem is here:
void getnewnode(int x)
{
struct node* temp = (struct node*)malloc(sizeof(struct node*));
temp->data = x;
temp->next = NULL;
temp->prev = NULL;
}
Specifically, in the first line. You probably want that to be sizeof(struct node), so that your pointer references a node, not a pointer to a node.
You also need to make your function return a value. So change it to:
void getnewnode(int x)
{
....
return temp;
}
The reason you're getting the error on this line:
struct node* newnode=getnewnode(x); /* void value not ignored as it ought to be. */
Is that your getnewnode function doesn't return a value. So newnode can't be assigned a value. That error should go away when you make the suggested change to getnewnode().

What's with the program why is it not printing any result?

struct node{
int data; struct node *next;
};
void push(struct node* head, struct node* n){
if(n!= NULL){
if(head==NULL)
head = n;
else {
n->next = head;
head = n;
}
} else printf("Cannot insert a NULL node");
}
struct node* pop(struct node* head){
if(head!=NULL){
struct node *n = head;
head = head->next;
return n;
} else {
printf("The stack is empty");
return NULL;
}
}
int main(){
int i;
struct node *head = NULL, *n;
for(i=15;i>0;i--){
struct node *temp = malloc(sizeof(struct node));
temp -> data = i;
temp->next = NULL;
push(head,temp);
}
n = head;
while(n!=NULL){
printf("%d ",n->data);
n=n->next;
}
return 0;
}
You need to pass the address of the pointer head to the function push. I your case the head is not getting modified because you are only passing the value in the head.
void push(struct node** head, struct node* n){
if(n!= NULL){
if(*head==NULL)
*head = n;
else {
n->next = *head;
*head = n;
}
} else printf("Cannot insert a NULL node");}
int main(){
int i;
struct node *head = NULL, *n;
for(i=15;i>0;i--){
struct node *temp = (struct node *)malloc(sizeof(struct node));
temp -> data = i;
temp->next = NULL;
push(&head,temp);
}
n = head;
while(n!=NULL){
printf("%d ",n->data);
n=n->next;
}
return 0;}
You are passing the head pointer by value to the function push(head,temp);. The changes to head done inside push will not be reflected in the main() function.
You should pass address of head to push().
push(&head, temp);
and inside push():
*head = n;
Similar change will be required for pop(). You can verify what I am saying by adding a printf inside the loop in main() as: printf("%p\n", head);. The value of head will remain unchanged.
BTW, it is good practice to add a \n at the end of statement inside printf, it flushes the stdout stream immmediately hence your output is printed immediately on stdout (your computer screen).

Resources