When printing out my linked list, what is displayed is not what I assumed it to be. How do I get the right output?
struct node{
int data;
struct node *next;
};
struct node *newNode(int data){
struct node *new_node=(struct node *) malloc(sizeof(struct node));
new_node->data=data;
new_node->next=NULL;
return new_node;
}
void push(struct node*** head, int data){
struct node* new_node=newNode(data);
new_node->next=(**head);
(**head)=new_node;
}
void create(struct node **number, char num[]){
int x=0;
while(x<strlen(num)){
int d=(int)(num[x]);
push(&number, d);
x++;
}
}
void printList(struct node *number){
while(number!=NULL){
printf("%d", number->data);
number=number->next;
}
printf("\n");
}
int main (void){
struct node *first;
char num1[10];
scanf("%s", num1);
create(&first, num1);
printList(first);
return 0;
}
Examples
Input : 1
Expected Output: 1
Actual Output : 49
Input : 12345
Expected Output: 12345
Actual Output : 5352515049
I think it is printing where the value is stored, not the value itself.
Correct me on that if that's wrong. Anyways how do I get the expected output I want.
The problem is that you are reading ascii values, and then trying to print integers, and since you need to store integers and not the ascii values all you need is a simple mathematical operation, i.e. subtract the ascii value of the digit '0', so to convert the ascii value of a digit to it's integer value all you need is
integer = ascii - '0';
here I fixed your code, because you were appending the value to the head of the list instead of it's tail
#include <stdlib.h>
#include <stdio.h>
struct node{
int data;
struct node *next;
};
struct node *newNode(int data)
{
struct node *new_node;
new_node = malloc(sizeof(struct node));
if (new_node == NULL) /* always check that malloc succeeded */
return NULL;
new_node->data = data;
new_node->next = NULL;
return new_node;
}
struct node *push(struct node *tail, int data)
{
struct node *new_node;
new_node = newNode(data);
if (tail != NULL)
return tail->next = new_node;
return new_node;
}
struct node *create(char *numbers)
{
size_t i;
struct node *head;
struct node *tail;
i = 0;
head = NULL;
tail = NULL;
/* since strings are 'nul' terminated, you just need to loop,
* until you find the 'nul' byte, strlen() expects that byte
* anyway.
*/
while (numbers[i] != '\0')
{
tail = push(tail, numbers[i++] - '0');
if (head == NULL)
head = tail;
}
return head;
}
void printList(struct node *number)
{
while (number != NULL)
{
printf("%d", number->data);
number = number->next;
}
printf("\n");
}
void freeList(struct node *number)
{
while (number != NULL)
{
struct node *last;
last = number;
number = number->next;
free(last);
}
}
int main(void)
{
struct node *first;
char numbers[10];
/* '%9s' prevents buffer overflow */
if (scanf("%9s", numbers) != 1)
return -1;
first = create(numbers);
printList(first);
freeList(first);
return 0;
}
You have a linked list which ends up in reverse order, and this is why your second example comes out in reverse order. If you print the linked list like this:
printf("%d ", number->data);
with a space, it would be clearer what is happening, output is ASCII values
53 52 51 50 49
But you are also confusing character values with numeric values. If you correct this,
printf("%c ", number->data);
you will get your original input characters in reverse order.
5 4 3 2 1
Related
So, I am trying to create a linked List where i take in strings from user then add them to the list and then delete the data at position 2. But i am having trouble with scanf (clarified in the output section) and also in the printing section. Any help would be appreciated.
The code
#include <stdio.h>
#include <stdlib.h>
struct node {
char *data;
char *begin;
char *end;
char *posi;
struct node *link;
};
struct node *add_begin(struct node *head, char *data) {
struct node *ptr = malloc(sizeof(*ptr));
ptr->data = data;
ptr->link = head;
return ptr;
}
struct node *add_end(struct node *head, char *data) {
struct node *ptr = malloc(sizeof(*ptr));
ptr->data = data;
ptr->link = NULL;
if (head == NULL) {
return ptr;
} else {
struct node *temp = head;
while (temp->link != NULL) {
temp = temp->link;
}
temp->link = ptr;
return head;
}
}
void add_at_post(struct node* head, char *data, int pos){
struct node *ptr=head;
struct node *ptr2=malloc(sizeof(struct node));
ptr2->data=data;
ptr2->link=NULL;
pos--;
while(pos !=1){
ptr=ptr->link;
pos--;
}
ptr2->link=ptr->link;
ptr->link=ptr2;
}
void delete_post(struct node* head, int position){
struct node*current= head;
struct node*previous= head;
if(head==NULL){
printf("is empty\n");
}
else if (position==1){
head=current->link;
free(current);
current=NULL;
}
else{
while(position!=1){
previous=current;
current=current->link;
position--;
}
previous->link=current->link;
free(current);
current=NULL;
}
}
int main() {
struct node *head = NULL;
char *data;
printf("Print at begin");
scanf("%s",data);
head = add_begin(head,data);//print at beginning of list
printf("Print at end");
scanf("%s",data);
head = add_end(head, data);//print at end of list
printf("Print at Position 2");
scanf("%s",data);
add_at_post(head,data,2);//print at position 2
delete_post(head,2);
for (struct node *ptr = head; ptr; ptr = ptr->link) {
printf("%s\n", ptr->data);
}
return 0;
}
The Expected Output
Print at begin
xxx
Print at end
yyy
Print at Position 2
ZZZ
xxx
zzz
The output I get. It calls the first scanf but skips the other 2. Then ends the RUN.
Print at begin
xxx
Print at end
Print at Position 2
This code is invalid in many places:
data does not reference valid memory
char *data;
printf("Print at begin");
scanf("%s",data);
you should allocate memory for ptr->data and copy as data may reference the same location on every call.
You do not check result of the malloc
My program takes in any number of words from the user, and stops only when the user types three asterisks (***). These words will be stored in a linked list and sorted, but the elements in the list are not sorted when I try to print the list. Why is this happening?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_STRING_LEN 32 // Limit on length of each string
/* Link list node */
struct Node
{
int data;
struct Node* next;
};
// Function to insert a given node in a sorted linked list
void sortedInsert(struct Node**, struct Node*);
// function to sort a singly linked list using insertion sort
void insertionSort(struct Node **head_ref)
{
// Initialize sorted linked list
struct Node *sorted = NULL;
// Traverse the given linked list and insert every
// node to sorted
struct Node *current = *head_ref;
while (current != NULL)
{
// Store next for next iteration
struct Node *next = current->next;
// insert current in sorted linked list
sortedInsert(&sorted, current);
// Update current
current = next;
}
// Update head_ref to point to sorted linked list
*head_ref = sorted;
}
/* function to insert a new_node in a list. Note that this
function expects a pointer to head_ref as this can modify the
head of the input linked list (similar to push())*/
void sortedInsert(struct Node** head_ref, struct Node* new_node)
{
struct Node* current;
/* Special case for the head end */
if (*head_ref == NULL || (*head_ref)->data >= new_node->data)
{
new_node->next = *head_ref;
*head_ref = new_node;
}
else
{
/* Locate the node before the point of insertion */
current = *head_ref;
while (current->next!=NULL &&
current->next->data < new_node->data)
{
current = current->next;
}
new_node->next = current->next;
current->next = new_node;
}
}
/* BELOW FUNCTIONS ARE JUST UTILITY TO TEST sortedInsert */
/* Function to print linked list */
void printList(struct Node *head)
{
struct Node *temp = head;
while(temp != NULL)
{
printf("%s \n ", temp->data);
temp = temp->next;
}
}
/* A utility function to insert a node at the beginning of linked list */
void push(struct Node** head_ref, int new_data)
{
/* allocate node */
struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
/* put in the data */
new_node->data = new_data;
/* link the old list off the new node */
new_node->next = (*head_ref);
/* move the head to point to the new node */
(*head_ref) = new_node;
}
// Main function
int main()
{
struct Node *a = NULL;
int index=1;
int i;
char * strings[MAX_STRINGS]; // Array of pointers
do
{
strings[index] = malloc(MAX_STRING_LEN * sizeof(char));
printf("Please input a word : ", index);
fgets(strings[index],MAX_STRING_LEN,stdin);
strtok(strings[index], "\n")=='\0';
}
while(strcmp(strings[index++], "***")!=0);
printf("\nThe input set, in alphabetical order:\n");
for (i = 1; i < index-1; i++)
{
push(&a, strings[i]);
}
insertionSort(&a);
printList(a);
free(strings[i]);
return 0;
}
Input:
pear
apple
***
Given output:
pear
apple
Expected output:
apple
pear
Hii I spent some time thinking what you wanted to do. And saw many problems with your code. I think you want something like this.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_STRING_LEN 32 // Limit on length of each string
#define MAX_STRINGS 100 // Limit the number of strings
struct Node {
char *data;
struct Node *next;
};
void sortedInsert(struct Node **head_ref, struct Node* new_node) {
struct Node *counter = *head_ref;
struct Node *previous = NULL;
while (counter != NULL && strcmp(counter->data,new_node->data) < 0){
previous = counter;
counter = counter->next;
}
if (previous != NULL) {
previous->next = new_node;
new_node->next = counter;
} else {
new_node->next = *head_ref;
*head_ref = new_node;
}
}
void push(struct Node **head_ref, char *new_data) {
struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
new_node->data = new_data;
new_node->next = NULL;
if (!head_ref) {
*head_ref = new_node;
return;
}
sortedInsert(head_ref,new_node);
}
void printList(struct Node *head) {
struct Node *temp = head;
while(temp != NULL) {
printf("%s\n", temp->data);
temp = temp->next;
}
}
void freeLinkedList(struct Node *head) {
struct Node *next;
while(head) {
next = head;
head = head->next;
free(next);
}
}
// Main function
int main() {
struct Node *a = NULL;
int index = 0;
int i;
char * strings[MAX_STRINGS]; // Array of pointers
do {
strings[index] = malloc(MAX_STRING_LEN * sizeof(char));
printf("Please input a word %d: ", index);
scanf("%s",strings[index]);
fflush(stdin);
} while(strcmp(strings[index++], "***") != 0 && index < MAX_STRINGS);
printf("\nThe input set, in alphabetical order:\n");
for (i = 0; i < index-1; i++) push(&a, strings[i]);
printList(a);
return 0;
}
I have tested it and it works fine.
If you have any doubts I would like to clear them.
If you want to know what's buggy in your code please feel free to ask.
This program should delete the N-node in a singly linked list. If i put N = 1 or N = 2 it's ok, the program works. But with N = 0 the output prints infinite nodes with random values (after deleting the node 0). I think the program can't see the new head. Thx for the help!
#include <stdio.h>
#include <stdlib.h>
#define N 0
struct node {
int data;
struct node *next;
};
void printlist(struct node *head){
struct node *current=head;
int i=0;
while (current!=NULL){
printf("node number %d \t : %d\n", i, current->data);
current=current->next;
i++;
}
}
int deletenode(struct node *head,int n){
struct node *current=head;
struct node *previous=head;
int i=0;
while(current!= NULL){
if (n==i && i!=0){
previous->next=current->next;
free(current);
return 1;
}
else if (n==i && i==0){
head=head->next;
free(current);
return 1;
}
i++;
previous=current;
current=current->next;
return 0;
}
printf("error\n");
exit(EXIT_FAILURE);
}
void main(){
struct node *n1=malloc(sizeof(struct node));
struct node *n2=malloc(sizeof(struct node));
struct node *n3=malloc(sizeof(struct node));
struct node *head=n1;
n1->data=5;
n1->next=n2;
n2->data=10;
n2->next=n3;
n3->data=15;
n3->next=NULL;
printf("\n\nbefore\n");
printlist(head);
deletenode(head,N);
printf("\n\nafter\n");
printlist(head);
}
I'm using currentas a temp pointer , because after the head shift on the second node i need a pointer to the old head and use free.
C always passes by value, so changing a parameter has no effect on the caller.
void foo(int i) {
i = 1234; // No effect on caller.
}
void foo(int *p) {
p = NULL; // No effect on caller.
}
If you want to modify a variable (such as the caller's head), you need to pass a pointer to it. (You can still change that to which a pointer references.)
int deletenode(struct node **head, int n) {
...
}
deletenode(&head, N);
Now, you could simply replace every instance of head in your code with (*head) to account for the new calling convention, but that would waste an opportunity for simplification. By having a pointer to a struct node *, we don't need to handle head (a struct node *) and prev_node->next (a struct node *) differently.
int delete_node_n(struct node **ptr, unsigned n) {
// Make `ptr` point to the pointer we want to modify.
// This will either be the `head` variable
// or the `next` field of some node.
while (1) {
if (!*ptr)
return 0;
if (!n)
break;
ptr = &( (*ptr)->next );
--n;
}
struct node *to_free = *ptr;
*ptr = (*ptr)->next;
free(to_free);
return 1;
}
So I have a program that takes a data string and a number on the end that is it's position in the priority that it's to be printed out. I'm required to use linked list's and I've figured out how to do so with that, however the way this program is executed is at the end of the data strings and priority's the user is supposed to enter NONE and the program executes. The problem is that my check with strcmp is forcing the user to enter NONE twice to execute the program. I don't think I'm using the scanf for string and int values correctly and that's where my problem lies but I'm not sure.
Here's a correct sample input:
andk81739wewe 7
qweod125632ao 3
lenlc93012wasd 0
093deaeiao12 5
13jadacas291 3
...
NONE
Here's what actually has to be typed for the program to execute
andk81739wewe 7
qweod125632ao 3
lenlc93012wasd 0
093deaeiao12 5
13jadacas291 3
...
NONE
NONE
Any ideas as to why a second NONE has to be typed for the program to recognize that none has been typed?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LARGE 100
struct node
{
char data[LARGE];
int position;
struct node* next;
};
void sortedInsert(struct node** first, struct node* new_node)
{
struct node* current;
if (*first == NULL || (*first)->position <= new_node->position)
{
new_node->next = *first;
*first = new_node;
}
else
{
current = *first;
while (current->next!=NULL &&
current->next->position > new_node->position)
{
current = current->next;
}
new_node->next = current->next;
current->next = new_node;
}
}
struct node *newNode(char *new_data,int position)
{
struct node* new_node =
(struct node*) malloc(sizeof(struct node));
strcpy(new_node->data,new_data);
new_node->position=position;
new_node->next = NULL;
return new_node;
}
void printList(struct node *head)
{
struct node *temp = head;
while(temp != NULL)
{
printf("%s \n", temp->data);
temp = temp->next;
}
}
int main(void) {
char job[LARGE],blank[1]={' '},*p,*q;
int number=0,x=0;
q=&blank[1];
struct node* first = NULL;
struct node *new_node = newNode(q,0);
printf("Please enter printing jobs\n");
while(x!=1){
if(strcmp(job,"NONE")==0){
x=1;
}
else{
scanf("%s", job);
scanf("%d", &number);
p=&job[0];
sortedInsert(&first, new_node);
new_node = newNode(p,number);
}
}
printf("Print Job in order from 9-0\n");
printList(first);
return 0;
}
Alternatively you may use following code segment. This one is more reduced and simplified approach.:
int main(void) {
char job[LARGE];
struct node *first = NULL;
struct node *new_node = NULL;
int number;
printf("Please enter printing jobs\n");
while(1)
{
scanf("%s", job);
if(!strcmp(job, "NONE"))
break;
scanf("%d", &number);
new_node = newNode(job, number);
sortedInsert(&first, new_node);
}
printf("Print Job in order from 9-0\n");
printList(first);
return 0;
}
I'm trying to get an integer of any size to a linked list in C. But when I print the list, a zero is printed always after the the integer.
Please note that I'm adding each digit of the integer to the head.(head has the 0th place of the integer)
#include <stdio.h>
#include <stdlib.h>
struct node
{
int digit;
struct node* next;
};
void get_number(struct node** head);
int create_node(int digit, struct node** head);
void printlist(struct node* head);
int main()
{
struct node* head1 = malloc(sizeof(struct node*));
get_number(&head1);
printlist(head1);
return 0;
}
int create_node(int digit, struct node** head)
{
struct node* tmp = malloc(sizeof(struct node*));
tmp -> digit = digit;
tmp -> next = *head;
*head = tmp;
}
void printlist(struct node* head)
{
struct node* curr = head;
if(!head)
return;
while(curr != NULL )
{
printf("%d",curr -> digit);
curr = curr -> next;
}
}
void get_number(struct node** head)
{
int k;
char c;
c = getchar();
while(c != '\n' && c != ' ')
{
k = c - '0';
create_node(k, head);
c = getchar();
}
}
when I input 123456, the output is 1234560.
I tried to find solution, but couldn't. Please help
You are one more node than necessary when you allocate to head1. You simply need to call the function get_number() as:
struct node* head1 = 0;
get_number(&head1);
which would set the next of the last element (i.e. the first allocate node) to 0 and rest of the logic would be fine.
You also need to correctly call malloc() and change the type of c to int (to handle EOF) as noted in the comments. My preferred way is to allocate memory is:
TYPE *p = malloc(sizeof *p);