weird number appears on output-C - c

I have made a simple list like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
struct node{
int am;
struct node *next;
};
typedef struct node node;
int main(){
int n;
node *head=(node *)malloc(sizeof(node));
node *cur=head;
printf("Give me a number:\n");
scanf(" %d",head->am);
cur=head;
while(1){
printf("Give me a number\n");
scanf(" %d",&n);
if(n==0)
break;
cur->am=n;
cur->next=(node *)malloc(sizeof(node));
cur=cur->next;
cur->next=null;
}
travel(head);
printf("Total nodes available :%d\n",count(head));
system("pause");
return 0;
}
Now travel is supposed to go through each node in the list and display the integer saved in each node.
void travel(node *h){
if(h==NULL)
return;
printf("Received data from node: \t %d\n",h->am);
travel(h->next);
}
Now the problem is that when travel is called it wont print the integer from the first node.It will also print another "Received data from node:" followed by a strange number.
For example
If i give 1,2,3,4 as inputs these are the results
Received data from node: 2
Received data from node: 3
Received data from node: 4
Received data from node: 4026432
Any ideas?

Now the problem is that when travel is called it wont print the
integer from the first node
This can be precisely known from this part of the main() function
printf("Give me a number:\n");
scanf(" %d",head->am); //this is wrong use of scanf("%d",&head->am);
cur=head;
while(1){
printf("Give me a number\n");
scanf(" %d",&n);
if(n==0)
break;
cur->am=n;
as I've mentioned you're scanning wrongly but that doesn't matter because later in the code in while loop you replace it this way...
you scan number and store it at head->am
then you assign head to cur so head->am and cur->am are both the same now... so in while loop when you first assign n to cur->am, it gets assigned to head->am. so this explains why you never get to print first node.
Solution:
to overcome it ... in while loop, before assigning cur->am=n try doing:
cur->next=(node *)malloc(sizeof(node));
cur=cur->next;
//then... assign
curr->am=n;
this way you'll not lose first node.
suggestion:
As someone has already said it's much easier to traverse/ travel the list using loops (never mind... if you want to do it recursively)
here's how you do it with the loops:
void travel(node *h)
{
if(h==NULL)
return; //list is empty,consider printing "list empty" :)
while(h!=NULL)
{
printf("Received data from node: \t %d\n",h->am);
h=h->next;
}
}
To put all together your code without changing the travel() function as suggested would be:
#include <stdio.h>
#include <stdlib.h>
struct node
{
int am;
struct node *next;
};
typedef struct node node;
void travel(node *h);
int main() //I have a habit of returning values from main() :)
{
int n;
node *head=(node *)malloc(sizeof(node));
node *cur=head;
printf("Give me a number:\n");
scanf(" %d",&head->am);
cur=head;
while(1)
{
printf("Give me a number\n");
scanf(" %d",&n);
if(n==0)
break;
cur->next=(node *)malloc(sizeof(node));
cur=cur->next;
cur->am=n; //NOTE:here's the change!
cur->next=NULL;
}
travel(head);
return 0; //just to signify successful compilation
}
void travel(node *h)
{
if(h==NULL)
return;
printf("Received data from node: \t %d\n",h->am);
travel(h->next);
}
Sample Input : 5 6 3 1 0
Sample Output :
Give me a number:
5
Give me a number
6
Give me a number
3
Give me a number
1
Give me a number
0
Received data from node: 5
Received data from node: 6
Received data from node: 3
Received data from node: 1

There are (at least) those issues:
The line scanf(" %d",head->am) is wrong since scanf() expects an address of the memory location of the expected value meaning &head->am.
Your loop scans a number and puts it in the current node and only after it creates a new node. Therefore, the first number you enter will be overridden (after fixing the first issue) and the last node created will contain random data because the loop will terminate after entering 0 but before putting anything in the last node.

I propose like this:
int main(void){
int n;
node anchor = {0, NULL};//dummy head
node *head, *cur = &anchor;
while(1){
printf("Give me a number\n");
scanf("%d", &n);
if(n==0)
break;
cur->next = malloc(sizeof(node));
cur = cur->next;
cur->am = n;
cur->next = NULL;
}
head = anchor.next;
travel(head);
printf("Total nodes available :%d\n", count(head));
return 0;
}

You are missing & at the first scanf:
scanf(" %d", &head->am);
But it could be made to do all the scanf inside the while:
int main(){
node *head=0;
node *cur=0;
node *prev=0;
while(1){
prev = cur;
cur=(node *)malloc(sizeof(node));
cur->next=NULL;
printf("Give me a number\n");
scanf("%d",&cur->am);
if(cur->am==0)
break;
if(head == NULL) head = cur;
if(prev != NULL) prev->next = cur;
}
travel(head);
printf("Total nodes available :%d\n",count(head));
return 0;
}
I hope I didnt make any mistake as I wrote it in this SO editor..
and as someone said, you should free the linked list .. but thats out of scope here..
HTH

Related

Linked lists in C with chars and integers (troubleshooting)

I want to programm a linked list in C, trying to apply everything I've learned so far.
I wrote this program to create a linked list:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node *head = NULL;
//Define struct node
struct node{
char * name;
int num;
struct node * next;
};
//Print List
void printList(){
struct node * temp = head;
while (temp != NULL){
printf("%s", temp->name);
printf("%d", temp->num);
temp = temp->next;
}
}
//Create New Node
struct node * newNode (char * name, int num){
struct node * newNode = (struct node*)malloc(sizeof(struct node));
newNode->name = name;
newNode->num = num;
newNode->next = NULL;
return newNode;
}
//Function to insert and sort Elements
void insertSorted (char * name, int num){
//Empty Liste -> Head is NULL
if (head == NULL){
head = newNode(name, num);
}
else if (strcmp(name, head->name) <=0){
// strcmp-output = -1 ->string 1 > string 2; 0 -> both strings are the same
struct node * temp = newNode(name, num);
temp->next = head;
head = temp;}
struct node * current = head; struct node *prev = NULL;
if (strcmp(name, current->name)>0){ //-> 1, string1 < string 2 ->insert after
while(current != NULL && strcmp(name, current->name)<=0){
prev = current;
current = current->next;
}
struct node * temp = newNode(name, num);
prev->next = temp;
temp->next = current;
}
}
//Test of the linked list
int main()
{
char name; int num;
//Testprogram
printf("Enter a name\n");
scanf("%s", &name);
printf("Enter a number\n");
scanf("%d", &num);
insertSorted(&name, num);
char name2; int num2;
printf("Enter a name\n");
scanf("%s", &name);
printf("Enter a number\n");
scanf("%d", &num2);
insertSorted(&name2, num2);*/
char name3; int num3;
printf("Enter a name\n");
scanf("%s", &name);
printf("Enter a number\n");
scanf("%d", &num3);
insertSorted(&name3, num3);
printList();
return 0;
}
Output example:
Input: Anna 1, Claudio 2, Berta 3
Output: 32Berta1
It somehow...makes the Names vanish and the numbers are in the wrong order too. I'm pretty new to programming, so I have troubles fixing this by myself.
Any help would be hugely appreciated :) Not only to fix the error, but also tips on how to program more...elegantly, so to say.
Thanks :)
//Edit:
Thank you for all the input so far! I messed up the input of the string while testing the program.
As suggested I tried to skip the part with the input, testing the linked list like this in main() (thanks Julien!):
insertSorted("Anna", 1);
insertSorted("Claudio", 2);
insertSorted("Berta", 3);
printList();
it results in the programm not executing and exiting with a negative number error code. Does this point to an infinite loop?
I haven't looked at the linked list details, but one issue I see is that you are using single char variable to store the names (which should be an array or characters). This lack of enough space to store the input make you program have an undefined behaviour after the call to scanf.
As #franji1 stated, try working step by step. If you want to check the code of your list, try testing:
insertSorted("Anna", 1);
insertSorted("Claudio", 2);
insertSorted("Berta", 3);
And check the result is what you expect. Once this is working, add the code asking for input from the user using scanf.
Im not an expert at C but since you mentioned code elegancy I can tell you this. You didn't need to use all these different if statements, you could use the while loop from the begining and insert after you find a name that is bigger than current. This will work even if it has to be inserted before the head node as long as you check that prev is not null. I hope I helped you and that you will find a solution to your problem!

C Programming -Linked List Implementation with characters

MY CODE:
#include<stdio.h>
#include<stdlib.h>
struct node{
char data;
struct node *next;
};
void main()
{ char A;
struct node *head,*ptr;
ptr=(struct node *)malloc(sizeof(struct node));
printf("Enter data for node 1 \n");
scanf("%c",&ptr->data);
head=ptr;
int i=2;
while(1)
{
ptr->next=(struct node*)malloc(sizeof(struct node));
ptr=ptr->next;
printf("\nEnter data for node %d:::\n",i);
scanf("%c",&ptr->data);
ptr->next=NULL;
i=i+1;
printf("Do you want to continue Y OR N");
scanf("%c",&A);
if(A=='Y')
continue;
else
break;
}
struct node *temp;
temp=head;
while(temp!=NULL)
{
printf("%c=>",temp->data);
temp=temp->next;
}
printf("NULL");
}
For this code I can only enter the first character data after that it is skipping the scanf portion within the while loop.
But when I am doing the same code with integer it is giving me the right output.
Here if I replace the same code instead of having characters I replace it by integers it works fine.
I couldnt find a way to fix it.
Plz help.
As stated in the comments your problem lies not in the linked list implementation, but in the code lines here.
scanf("%c",&ptr->data); //line number 14
scanf("%c",&ptr->data); //line number 22
scanf("%c",&A); //line number 26
in all these lines %c consumes the new line character(\n) instead of the users input.
To correct the issue, you can place a whitespace in front of the %c like this,
scanf(" %c",&ptr->data); //line number 14
scanf(" %c",&ptr->data); //line number 22
scanf(" %c",&A); //line number 26

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.

Inserting element in linked list after the biggest element in the list

I've been smashing my head here to see if I could find a solution but after few infinite loops, here's the code I'd like to be reviewed:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_TREE_STRING 100
typedef struct Node {
char val;
struct Node *next;
} node;
node *create_list(char *list_string) {
node *momentary=NULL, *new=NULL, *head;
int i;
for(i=0; i<strlen(list_string); i++) {
new = (node *)malloc(sizeof(node));
new->val = list_string[i];
new->next = NULL;
if (!momentary) head = new;
else momentary->next = new;
momentary = new;
}
return head;
}
int print_list(node *head) {
node *momentary;
if(!head) return -1;
for(momentary=head; momentary!=NULL; momentary=momentary->next)
printf("%c ", momentary->val);
printf("\n");
return 0;
}
node *find_biggest(node *head) {
node *momentary=NULL, *biggest=head;
if (head==NULL) return NULL;
for (momentary=head; momentary!=NULL; momentary=momentary->next) {
if (momentary->val > biggest->val) biggest = momentary;
}
return biggest;
}
void insert_after_biggest(node **head, node **biggest, char val) {
node *p = *head, *temp=NULL;
*head = p->next;
if(*head!=NULL){
if(p->val==(*biggest)->val){
temp=p;
p->next=temp;
p->val=temp->val;
p->next=NULL;
*biggest=p;
p->next=(*biggest);
p->val=(*biggest)->val;
//*biggest=p;
p->next=NULL;
//temp=p;
p->next=temp;
p->val=temp->val;
}
else if(p->val<(*biggest)->val){
*head = p->next;
}
}
}
int main () {
node *head=NULL, *biggest=NULL;
int menu_choice;
char c, val, list_string[MAX_TREE_STRING];
setbuf(stdout, NULL);
do {
menu_choice = 0;
printf("\n1 Create list \n2 Print");
printf("\n3 Insert after biggest");
printf("\n4 exit\n");
scanf("%d", &menu_choice);
switch (menu_choice) {
case 1:
if (head) {
printf("List exist.\n");
break;
}
printf("Enter list as digits without spaces: ");
scanf(" %s", list_string);
head = create_list(list_string);
break;
case 2:
print_list(head);
break;
case 3:
scanf(" %c", &val);
insert_after_biggest(&head, &biggest, val);
break;
case 4:
break;
default:
while((c=getchar())!='\n' && c!=EOF);
}
} while(menu_choice!=4);
return 0;
}
Now the task here is:
Write a function "insert_after_biggest" so that the new elements are
put behind the element with the highest value and complexity of the
function must be O (1). In other words, the function "find_biggest"
that has complexity of O (n) can be called only if the "biggest" has
not yet been defined. If the list has no elements , it still needs to
be first.
Here's a console example to have clearer picture:
1|<-Insert into linked list option|
Enter list as digits without spaces: 683 |<-Prompt and entered value|
3 |<-Option(the function)|
2 |<-Number to be inserted|
2 |<-Print option|
6 8 2 3|<-Output|
3 |<-Option|
8 |<-Number to be inserted|
2 |<-Print option|
8 |<-Output|
I've been typing this code myself and I have no idea anymore how to look at this.
I would humbly ask if someone can help me to solve this, the code compiles but executing the option 3 in the console only makes it run in infinite loop, resulting in crashing the console.
The specific: how to solve it (step by step) and how it should look like(the done code, possibly included here?).
Thank you.
If you can assume that
1) You don't need to remove elements
You merely need to keep an extra pointer that points to the node with the largest value at all times. It's nice that you are allowed to scan the list for the largest if you've never called
insert_after_biggest, but that's not even necessary. Call that node max, and the pointer to max p_max.
For each insertion
a) The value you're about to insert is larger than the value held by max, in which case you insert the new value, and change p_max = p_new.
n_new->next = p_max;
p_max = p_new;
b) The value you're about to insert is larger than the value held buy max, in which case simply insert and leave p_max unchanged.
For insert_after_max
you explicitly do
p_new->next = p_max->next;
p_max->next = p_new;
Or if the new value is larger then do as described above.
Since you don't have to scan the list to insert, the complexity of insertion is O(1)

Resources