cstringlinked-listoutputcharacter-arrays

Why does my link list have the wrong data?


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.


Solution

  • 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;
    }