【问题标题】:Scanf() taking 0 instead of Float keyboard inputScanf() 取 0 而不是 Float 键盘输入
【发布时间】:2017-10-30 05:01:33
【问题描述】:

我遇到了 scanf() 函数将 0 作为输入而不是通过键盘进行实际输入的问题。 手头的任务非常简单。我需要使用函数 upis 将元素添加到链表中,然后打印所有元素并清除列表。但是,我总是打印出 0。

起初我认为我的 upis 函数或打印和清除列表的代码块有问题,但经过一些修补和添加 printf("BROJJJJJJJJJJJ:",broj);(打印我刚刚输入的数字),我意识到我一直在那里得到 0,所以上面一行中的 scanf() 肯定有什么问题。

我尝试在 f 之前添加空格,但这根本没有帮助(scanf("%f", &broj);)。

由于部分代码不是英文的,这里只是一个快速参考指南:

cvor = 节点

新 = 新

glava = 根

sljed = 下一个

代表 = 结束

broj = 号码

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

【问题讨论】:

    标签: c io linked-list floating-point scanf


    【解决方案1】:

    您的列表代码是正确的,您以%d 格式打印元素,而它们是浮点数,因此请更改:

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

    到这里:

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

    并且应该看到正确的结果。例如

    ./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  
    

    更多解析答案:

    编译时启用一些警告,你应该得到:

    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.
    

    试试这个而不是你的调试尝试:

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

    当然,我强烈建议您注意其他两个打印件,除非您想要不准确的打印件。


    没有malloc.h,为了使用malloc(并且免费),这样做:

     #include <stdlib.h>
    

    不是导致您的错误的原因,而是Do I cast the result of malloc? 没有。


    我尝试在...之前添加空格

    这在处理字符时很有用。我会在Caution when reading char with scanf (C) 中进一步讨论这个问题。

    【讨论】:

    • 感谢您的帮助,我搞砸了打印件。我正在使用 GCC (C:\asp>gcc -ansi -Wall -pedantic-errors -o zad1.exe zad1.c) 但它没有返回任何警告。一切看起来都很干净。
    • 我只使用了-Wall 标志@scriptybusiness,正如您在我的回答中看到的那样。你很亲密,干得好! =)
    【解决方案2】:

    三个问题:

    1. 不测试来自scanf 的返回值总是一个错误
    2. 您不会扫描输入中的换行符或空格,因此进一步的 scanf 调用可能会返回 0(您没有对其进行测试;空格不能是浮点数的一部分)并保持关联的参数不变。使用类似这样的东西,它会在浮点数之前跳过任意数量的空白字符:

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

    3. int 与 float 格式不匹配。

    【讨论】:

    • 赞成建议检查scanf()的返回值,这有时会导致麻烦。
    • 感谢您的回答,但在这种情况下,我搞砸了 printf() 函数。
    猜你喜欢
    • 2018-02-15
    • 2015-04-12
    • 1970-01-01
    • 1970-01-01
    • 2012-04-01
    • 1970-01-01
    • 2013-01-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多