Linked list in C is not printing - c

I think it is not printing because I am not inserting into the list correctly. I see most people allocate space outside of the loop, but I am not sure that is the case.
#include <stdio.h>
#include <stdlib.h>
typedef struct intList {
int number;
struct intList *next;
} INT_LIST;
int main() {
INT_LIST *start = NULL, *temp;
INT_LIST *trvPtr = start;
/* Insert into list */
while (temp->number != 0) {
temp = malloc(sizeof(INT_LIST));
printf("Enter your integer: ");
scanf("%d", &(temp->number));
temp->next = start;
start = temp;
}
printf("List is: \n");
while (trvPtr != NULL) {
printf("%d", trvPtr->number);
trvPtr = trvPtr->next;
}
return 0;
}

temp is uninitialized and points to garbage. Checking temp->number != 0 is undefined behavior.
You can solve this with a do/while loop. The loop will always run once. Allocate temp, set it, then check.
INT_LIST *start = NULL, *temp;
do {
temp = malloc(sizeof(INT_LIST));
printf("Enter your integer: ");
scanf("%d", &(temp->number));
temp->next = start;
start = temp;
} while(temp->number != 0);
Note that your list will always start with a value of 0. To avoid this, check the input before doing anything else. Use while(1) for an infinite loop and use break to end the loop.
INT_LIST *start = NULL;
while(1) {
int input;
printf("Enter your integer: ");
scanf("%d", &input);
if(input == 0) {
break;
}
INT_LIST *temp = malloc(sizeof(INT_LIST));
temp->number = input;
temp->next = start;
start = temp;
}
When you print, trvPtr will always be NULL; it will not track changes to start. You have to assign it to the new value of start.
printf("List is: ");
INT_LIST *trvPtr = start;
while (trvPtr != NULL) {
printf("%d ", trvPtr->number);
trvPtr = trvPtr->next;
}
puts("");
Note that you're not limited to declaring all the variables at the start of the function.

I have made some modifications/corrections in your code and the following should work -
Correct Code -
#include <stdio.h>
#include <stdlib.h>
typedef struct intList {
int number;
struct intList *next;
} INT_LIST;
int main() {
INT_LIST *start = NULL, *temp;
temp = (INT_LIST*)malloc(sizeof(INT_LIST));
INT_LIST *trvPtr = temp;
/* Insert into list */
do {
printf("Enter your integer: ");
scanf("%d", &(temp->number));
start = temp;
temp->next = (INT_LIST*)malloc(sizeof(INT_LIST));
temp = temp->next;
}while (start->number != 0);
temp->next=NULL;
printf("List is: \n");
while (trvPtr->next != NULL) {
printf("%d", trvPtr->number);
trvPtr = trvPtr->next;
}
return 0;
}
SAMPLE OUTPUT :
Enter your integer: 1
Enter your integer: 2
Enter your integer: 3
Enter your integer: 0
List is:
1230
If you don't want the 0 to be printed, include temp = start, right after the first while loop ends.
Explanation :
Firstly, in your code, you hadn't assigned temp anything. It should have been allocated space and assigned something first or else the statement temp->number != 0 is just undefined behavior.
Nextly, I have used start to check for the last value entered by the user. If it is 0, the loop will break. Do note I have converted the loop into do-while loop, since start is NULL at the beginning.
Lastly, once the loop ends, I have set the next of temp to null so that the printing loop will execute correctly. In your code, this part also had a mistake since you had assigned NULL to trvPtr but never changed the value. So, in your case, the loop would never have executed.
NOTE : It's always better to mention the cast-type explicitly while using malloc. Some compiler would give warnings/errors. So, I have modified that as well wherever you have used malloc()

Related

What's the problem in this program of Single Linked list?

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
struct node {
int data;
struct node* nextptr;
} * manode;
void add();
void delete ();
void display();
int main()
{
int choice;
int echoice;
while (choice != 4) {
printf("\n \t ENTER YOUR CHOICE FOR SINGLE LINKED LIST ");
printf("\n \t 1. ADD ELEMENT ");
printf("\n \t 2. DISPLAY ELEMENT ");
printf("\n \t 3. DELETE ELEMENT ");
printf("\n \t 4. EXIT ");
scanf("%d", &choice);
switch (choice) {
case 1:
while (echoice != 0) {
add();
printf("\n DO YOU WANT TO CONTINUE 1/0 ");
scanf("%d", &echoice);
}
break;
case 2:
display();
break;
case 3:
delete ();
break;
case 4:
exit(0);
break;
default:
printf("\n \t WRONG VALUE ENTERED ");
};
}
return 0;
}
#Add function is responsible to add the first node and all the remaining nodes as well.
void add()
{
struct node *tmp, *tmp2;
tmp = malloc(sizeof(struct node));
tmp2 = malloc(sizeof(struct node));
int value;
printf(" ENTER THE VALUE YOU WANT TO ENTER ");
scanf("%d", &value);
if (manode == NULL) {
manode = malloc(sizeof(struct node));
printf(" FIRST ENTRY ");
manode->data = value;
manode->nextptr = NULL;
tmp = manode;
printf("THE DATA %d ", manode->data);
}
else {
if (tmp2 == NULL) {
printf("\n MEMORY ALLOCATION FAILED");
}
else {
tmp2->data = value;
tmp2->nextptr = NULL;
tmp->nextptr = tmp2;
tmp = tmp->nextptr;
}
}
//manode=tmp;
}
void display()
{
struct node* tmp1;
if (manode == NULL) {
printf(" MEMORY ALLOCATION FAILED ");
}
else {
tmp1 = manode;
while (tmp1 != NULL) {
printf("\n%d DATA IS DISPLAY \n", tmp1->data);
tmp1 = tmp1->nextptr;
}
}
}
void delete ()
{
struct node* tmp;
if (manode == NULL) {
printf("NOTHING TO DELETE ");
}
else {
tmp = malloc(sizeof(struct node));
}
}
Kindly copy and compile the code, it's working but it doesn't display the contents in the list. Kindly copy and compile the code, it's working but it doesn't display the contents in the list.Kindly copy and compile the code, it's working but it doesn't display the contents in the list.Kindly copy and compile the code, it's working but it doesn't display the contents in the list.
As I see, there are a number of issues with your code.
do not use conio.h. This thing is from the '80s and adds nothing to a modern program but problems
never try to implement an ADT --- any container such as list, set, map --- as a node. It will only give you trouble: a list is a collection of nodes. Each node has a payload, some data. This data can have a key, something used to compare records. A node is not a list. A node is not the data. A list is not a node. As seen from the list, the data are the nodes. This way you can use anything as data in your list. And this is the purpose of a container: write once, use always. And the list has metadata, some obvious controls such its size, starting addres, ending address and possibly other stuff.
do not use void(). Is a waste, sometimes an error. In your case is an error. All pointers are buried inside the functions and die there. So display() and add() does not work
do not typedef pointers. It is a mess. In you case manode is a pointer. How are someone, even yourself a few days from now, remember what is what? If manode is a typedef for a struct everyone knows that
manode* many_nodes[30]
declare many_nodes as a pointer to an array of structs. The asterisk tells everything: many_nodes is a pointer to manode. BTOS if you bury the * inside the typedef you will always need to refer to the code in the header.
do not mix code of the list with I/O. It will only make your like harder. You have a list of simple int, so declare add() for instance as int add(int item, List* the_list). This way is more readable and you can write a simple loop to fill the list with a few hundred or just one node and start testing.
if you have a menu just write it as a function that returns the user option. But add it later to the program. A menu serves nothing to the list and to the program
scanf() was not written to read input from the keyboard. It is for scan formatted input, hence the name. It will always give you trouble when reading from stdin. But do your part and at least always test the return of scanf(). ALWAYS. rtfm.
do not write \n \t on a printf. Use just tabs or count the spaces.
always initialize all variables. In your code you start testing choice and echoice with no value set.
what is the point of having a loop on option 1, add since anyway the user will need to input an answer and enter 1?
Back to your program
See below your code rearranged using some of the things I wrote above. Compare with your code
Sample Code
#include <stdio.h>
#include <stdlib.h>
typedef struct st_node
{
int data;
struct st_node* nextptr;
} Node;
typedef struct tlist
{
unsigned size;
Node* start;
} List;
int add(int, List*);
int delete (int, List*);
int display(List*);
int menu();
int main(void)
{
List one;
one.size = 0;
one.start = NULL;
int res = menu();
printf("menu returned %d\n", res);
display(&one);
for( int i = 0; i<10; i+=1)
add(i,&one);
display(&one);
return 0;
}
int add(int value, List* l)
{
if ( l == NULL ) return -1;
Node* node = (Node*) malloc(sizeof(Node));
// simplest: insert at the beginning
node->nextptr = l->start;
node->data = value;
l->start = node;
l->size += 1;
return l->size;
};
int display(List* l)
{
if ( l== NULL) return -1;
if ( l->size == 0 )
{
printf("\n\tlist is empty\n\n");
return 0;
}
else
{
printf("\n\t%d elements in the list\n\n", l->size);
};
Node* p = l->start;
for( unsigned i = 0; i< l->size; i+=1)
{
printf("%3d: %11d\n", 1+i, p->data);
p = p->nextptr;
};
return l->size;
}
int delete (int v, List* l)
{
return 0;
}
int menu()
{
int choice = 0;
int res = 0;
printf(
"\n\tENTER YOUR CHOICE FOR SINGLE LINKED LIST:\n\
\n\t\t1. ADD ELEMENT\
\n\t\t2. DISPLAY ELEMENT\
\n\t\t3. DELETE ELEMENT\
\n\t\t4. EXIT\
\n\n\t\tYour choice: ");
while( res != 1 )
{
res = scanf("%d", &choice);
if ( choice >=1 && choice <= 4 ) return choice;
};
return 4;
}
OUTPUT
ENTER YOUR CHOICE FOR SINGLE LINKED LIST:
1. ADD ELEMENT
2. DISPLAY ELEMENT
3. DELETE ELEMENT
4. EXIT
Your choice: 2
menu returned 2
list is empty
10 elements in the list
1: 9
2: 8
3: 7
4: 6
5: 5
6: 4
7: 3
8: 2
9: 1
10: 0
And it is just an example of stuff using a more manageable list.

Add words received from the user to the linked-list in C programming

#include <stdio.h>
#include <stdlib.h>
struct node {
char *str;
struct node *next;
};
struct node *start = NULL;
struct node *temp = NULL;
struct node *q = NULL;
void sonaEkle(char *veri) {
struct node *eklenecek = (struct node *)malloc(sizeof(struct node));
eklenecek->str = veri;
eklenecek->next = NULL;
if (start == NULL) {
start = eklenecek;
} else {
q = start;
while (q->next != NULL) {
q = q->next;
}
}
}
void yazdir() {
q = start;
while (q->next != NULL) {
printf("%s", q->str);
q = q->next;
}
printf("%s", q->str);
}
int main() {
char *veri;
while (1 == 1) {
printf("enter string");
scanf("%s", veri);
sonaEkle(veri);
yazdir();
}
return 0;
}
I have created a Linked list.
This linked list adds the string it received from the user to the end. But my code is giving a loop error. How can I fix this?
for example: user input:abc bcd cde
output:abc => bcd => cde
This is an infinite loop
while(1 == 1) {
printf("enter string");
scanf("%s",veri);
sonaEkle(veri);
yazdir();
}
Rewrite it in this way
while( puts("enter string") && scanf("%s",veri) == 1 ) {
sonaEkle(veri);
yazdir();
}
And also you need to allocate memory for veri before you can use it in scanf. But you could as well just making it an array.
char veri[SIZE];
There are multiple problems with the code
char *veri;
while(1 == 1){
First statement veri needs memory, since it is a pointer, you need some thing like this veri = malloc(somesize);
Second statement is an infinite loop, you need some termination point, better use something like below to break the infinite loop.
while(1){
// after malloc
scanf("%s",veri);
//enter exit whenever you want to exit from program.
if(strcmp(veri,"exit") == 0)
break;
Function sonaEkle you are allocating memory for struct node* , but you are not returning updated nodes address start
you need to have sonaEkle like this struct node* sonaEkle(char *veri) and return start after every update and no need to cast malloc.
4)
else {
q=start;
while(q->next != NULL) {
q=q->next;
}
The above part just iterates list, you need to add new nodes to q->next when it reaches to NULL and return start afterwards in order to have next elements in the list.
Correct all those problems , to make you program work.
NOTE:
check the pointers for NULL after every malloc
free the malloc'ed memory once you are done with your program.

free the memory in C

The result of code 1 is still 10 after you free pointer p and p is not NULL.
the inputs of code 2 are 5 (length) and 1 2 3 4 5 for the value of each node, but the output is nothing under the condition that all the following nodes are not NULL.
My question is that based on the logic of code 1, shouldn't all the values of nodes be printed because they are not NULL?
Can anyone explain to me? Thank you so much!
code 1:
#include <stdio.h>
#include <stdlib.h>
int main() {
int *p = (int*)malloc(sizeof(int));
*p = 10;
free(p);
if (p != NULL) {
printf("%d\n", *p);
}
return 0;
}
code 2:
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
struct Node *next;
int value;
} Node, *list;
list create_Node() {
list head = (list)malloc(sizeof(Node));
if (!head)
exit(-1);
list tail = head;
int len;
int val;
printf("Please enter the length of the list:\n ");
scanf("%d", &len);
for (int i = 0; i < len; i++) {
list new = (list)malloc(sizeof(Node));
if (!new)
exit(-1);
printf("Please enter the value of the node:\n ");
scanf(" %d", &val);
new->value = val;
tail->next = new;
tail = new;
}
return head;
}
int delete_List(list l) {
if (l == NULL) {
printf("List is empty!");
exit(-1);
}
list temp;
while (l) {
temp = l->next;
free(l);
l = temp;
}
return 1;
}
int main() {
Node *n = create_Node();
n = n->next;
delete_List(n);
while (n->next != NULL) {
printf("%d\n", n->value);
n = n->next;
}
return 0;
}
...based on the logic of code 1...
Code 1 accesses freed memory (a so-called dangling pointer), which is undefined behavior. Anything can happen, including, but not limited to, your program crashing, the last value being returned (= the behavior you observed) or the program doing something completely unexpected.
Thus, you cannot infer anything from "the logic of code 1".
having
int main(){
int *p = (int*)malloc(sizeof(int));
*p = 10;
free(p);
if(p!=NULL)
{
printf("%d\n",*p);
}
return 0;
}
My question is that based on the logic of code 1, shouldn't all the values of nodes be printed because they are not NULL??
Except in the case there are no more memory the malloc will works and return a non null value, after the free the value of p is unchanged and still non null so the code try to read in the free memory and this is an undefined behavior
There are better way to ( try to) print a random value :-)
in code 2 this is the same, you access to free memory, both in the test of the while and in the printf and the value to assign n

wrong result of total nodes in C

I have the following program which creates a simple linked list of chars.
typedef struct letter{
char c;
struct letter *next;
}letter;
int count(letter *c){
int n = 0;
letter *t = c;
while(t){
n++;
t = t->next;
}
t = NULL;
return n;
}
int main(){
letter *head = (letter*)malloc(sizeof(letter));
letter *cur = head;
int n;
printf("Give me a number:");
scanf("%d",&n);
while(n > 0){
printf("Give me a char:");
scanf(" %c",&cur->c);
cur->next = (letter*)malloc(sizeof(letter));
cur=cur->next;
cur->next = NULL;
printf("Give me a number:");
scanf("%d",&n);
}
cur = head;
printf("Total nodes: %d",count(head));
system("pause");
return 0;
}
I am filling the list with characters until the user presses 0.The problem is that when I try to output the total number of nodes using count() function I get wrong result.For example consider the following input:
1
a
2
b
3
c
0
the result is:
Total nodes:4
which is wrong. It should be Total nodes:3
Can you explain why this is happening?
When you create the list you also create the first node, but you never assign its char a value.
I have two suggestions on how to fix your problem:
Don't count the first node. Always skip it when retrieving values or counting list length. This is slightly easier to implement, IMO.
or
Let the head point to NULL when the list is empty. Not that this solution means that the head pointer changes it's value when you insert the first element, so you need to pass the list pointer by reference to your insert/delete functions.
cur->next = (letter*)malloc(sizeof(letter));
cur=cur->next;
cur->next = NULL;
This code will create a node every time loop executes, so after 3rd char entry, node will be created without containing any value.
so in count loop it will result in 4 nodes.
Modified Loop: Run and check
while(n > 0){
printf("Give me a char:");
scanf(" %c",&cur->c);
cur->next = NULL;
printf("Give me a number:");
scanf("%d",&n);
if(n > 0)
{
cur->next = (letter*)malloc(sizeof(letter));
cur=cur->next;
}
}

Linked List Appcrash

I was trying to do an example about linked list. First, I added the values to the variables and there was no problem. But when I tried to get values from user, the program crashed when entering midterm 2 grade. I tried other input functions but the result is same. Where is the problem?
#include <stdio.h>
struct student
{
char *name;
int m1,m2,final;
struct student* next;
};
main()
{
addStudent();
system("PAUSE");
}
addStudent()
{
struct student *node = NULL;
struct student *firstnode;
firstnode = (struct student *)malloc(sizeof(struct student));
node = firstnode;
printf("press 0 to exit \n");
while(1)
{
printf("Student name: ");
scanf("%s", node->name)
if(node->name == "0") break;
printf("Midterm 1: ");
scanf("%d", node->m1);
printf("Midterm 2: ");
scanf("%d", node->m2);
printf("Final: ");
scanf("%d", node->final);
node->next = (struct student *)malloc(sizeof(struct student));
node = node->next;
}
node->next = NULL;
node = firstnode;
while(node->next);
while(node->next != NULL)
{
printf("%s - ",node->name);
printf("%d ", node->m1);
printf("%d ", node->m2);
printf("%d ", node->final);
node = node->next;
}
system("PAUSE");
return 0;
}
Fix 1
Remove the line
while(node->next);
Reason: It will put you on an infinite loop in most cases and it is unnecessary.
Fix 2
Replace the loop
while(node->next != NULL) {
}
with
if (node->next != NULL) {
while (node->next->next != NULL) {
}
}
Reason: You are allocating one additional struct each time and keeping it empty for reading next time. So the Linked List will end before the next becomes NULL.
Fix 3
Replace following in struct
char *name;
with
char name[80];
Reason: Memory not being allocated.
Fix 4
Replace at all occurrences of scanf (except for name)
scanf("%d", node->m1);
with
scanf("%d", &node->m1);
Reason: scanf needs memory location of data to be read.
Good luck
Your code has multiple errors.
To start with, the first scanf("%s", node->name) is missing its terminating semicolon.
Next, your function signatures are sloppy. main() should be int main(void). addStudent() should be int addStudent(void). (Or, get rid of its return 0 and let it return void.) Since you don't pre-declare addStudent(), you should define it before main() so that main() can know about it.
The crash, though, is because you haven't allocated memory for node->name. You've allocated memory for a node, but that doesn't give you space to put the name.

Resources