1

I'm having problems with scanf() function taking 0 as input instead of the actual input via keyboard. The task at hand is pretty simple. I need to add elements to a linked list using function upis, and then print all the elements and clear the list. However, I kept getting 0s printed out.

At first I thought there was some problem with my upis function or with the block of code where I print and clear the list, but after some tinkering and adding printf("BROJJJJJJJJJJJ:",broj); (printing the number I just entered), I realised I kept getting 0s there, so there must be something going on with scanf() in the above line.

I tried adding blank space before f, but that didn't help at all (scanf("%f", &broj);).

Since parts of code are not in English, here's just a quick reference guide:

cvor = node

novi = new

glava = root

sljed = next

rep = end

broj = number

#include <stdio.h>
#include <malloc.h>

typedef struct cvor {
    float element;
    struct cvor *sljed;
} cvor;

int upis(cvor **glava, cvor **rep, float *broj) {
    cvor *novi;
    novi=(cvor*)malloc(sizeof(cvor));
    if (novi == NULL) return 0;
    novi->element = *broj;
    novi->sljed = NULL;
    if (*glava == NULL) {
        *glava = novi;
        *rep = novi;
    }
    else {
        (*rep)->sljed = novi;
        *rep = novi;
    }
    printf("%d  ", (*glava)->element);
    return 1;
}

int main(void) {
    cvor *glava=NULL, *rep=NULL, *p=NULL;
    float broj;
    int n,i;

    do {
        printf("Unesite n<=10\n");
        scanf("%d", &n);
    } while (n<=0 || n>10);

    /* upisivanje */
    for (i=0; i<n; i++) {
        printf("Unesite %d. clan liste\n", i+1);
        **scanf("%f", &broj);**
        **printf("BROJJJJJJJJJJJ:",broj);**
        if (!(upis(&glava, &rep, &broj))) printf ("\nUpis neuspjesan\n");
        else printf ("\nUpis uspjesan\n");
    }

    /*ispisivanje i brisanje (od pocetka)*/
    for (;glava;) {
        printf("%d  ", glava->element);
        p = glava;
        glava = glava->sljed;
        free(p);
    }

    return 0;
}
gsamaras
  • 71,951
  • 46
  • 188
  • 305

2 Answers2

2

Three problems:

  1. not testing the return value from scanf is always a bug.
  2. you don't scan the newlines or spaces in the input, so further scanf calls likely return 0 (which you didn't test for; a space can't be part of a float) and leave the associated argument unaltered. Use something like this which skips any number of white space characters prior to a float:

    if (scanf (" %f", &broj) == 1) { /* got something */ } else { /* EOF or error */ }

  3. Format mismatches int versus float.

Jens
  • 69,818
  • 15
  • 125
  • 179
0

Your code of the list is correct, you print the elements with %d format, while they are floats, so change this:

printf("%d  ", (*glava)->element);

to this:

printf("%f  ", (*glava)->element);

And should see the correct results. E.g.

./a.out 
Unesite n<=10
4
Unesite 1. clan liste
3.14
3.140000  
Upis uspjesan
Unesite 2. clan liste
2.78
3.140000  
Upis uspjesan
Unesite 3. clan liste
1.11
3.140000  
Upis uspjesan
Unesite 4. clan liste
2.22
3.140000  
Upis uspjesan
3.140000  2.780000  1.110000  2.220000  

More analytical answer:

Compile with some warnings enabled, and you should get:

Georgioss-MacBook-Pro:~ gsamaras$ gcc -Wall main.c 
main.c:23:20: warning: format specifies type 'int' but the argument has type
      'float' [-Wformat]
    printf("%d  ", (*glava)->element);
            ~~     ^~~~~~~~~~~~~~~~~
            %f
main.c:41:34: warning: data argument not used by format string
      [-Wformat-extra-args]
        printf("BROJJJJJJJJJJJ:",broj);
               ~~~~~~~~~~~~~~~~~ ^
main.c:48:24: warning: format specifies type 'int' but the argument has type
      'float' [-Wformat]
        printf("%d  ", glava->element);
                ~~     ^~~~~~~~~~~~~~
                %f
3 warnings generated.

Try this instead of your debugging attempts:

printf("BROJJJJJJJJJJJ: %f\n",broj);

Of course, I strongly advice you to take care the other two prints, unless you want inaccurate prints.


There is no malloc.h, in order to use malloc (and free), do this:

 #include <stdlib.h>

Not what causing your errors, but Do I cast the result of malloc? No.


I tried adding blank space before ...

This is useful when dealing with characters. I discuss this further in Caution when reading char with scanf (C).

gsamaras
  • 71,951
  • 46
  • 188
  • 305
  • Thanks for the help, I screwed up the prints. I was using GCC (C:\asp>gcc -ansi -Wall -pedantic-errors -o zad1.exe zad1.c) but it didn't return any warnings. Everything looked clean. – scriptybusiness May 29 '17 at 21:00
  • I used only `-Wall` flag @scriptybusiness, as you can see in my answer. You were close, good job! =) – gsamaras May 29 '17 at 21:03