【问题标题】:Unable to find bug in this C program在这个 C 程序中找不到错误
【发布时间】:2010-07-31 14:38:11
【问题描述】:

我在这个 C 程序中找不到错误。

#include <stdio.h>

int main()
{ 

    struct book 
    { 
        char name ; 
        float price ; 
        int pages ; 
    } ;

    struct book b[3] ;
    int i ; int k;
    for ( i = 0 ; i <= 2 ; i++ )
    { 
        printf ( "\nEnter name, price and pages: " ) ;
        k = scanf ( "%c %f %d", &b[i].name, &b[i].price, &b[i].pages ) ;
    } 
    for ( i = 0 ; i <= 2 ; i++ ) 
        printf ( "\n%c %f %d", b[i].name, b[i].price, b[i].pages ) ;
    //getch();
    return 0;
}

运行时间:

Enter name, price and pages: a 1 1

Enter name, price and pages: b 2 2

Enter name, price and pages:
a 1.000000 1

 7922540190797673100000000000000000.000000 4200368
b 2.000000 2

我想将a 1 1b 2 2c 3 3 作为每个 scanfs 的输入,但它没有等待我在第三个 scanf 中的输入。为什么这样?为什么它会将我的第二次输入读取到数组的第三个元素中?

【问题讨论】:

  • 现在您会发现 NOBODY 使用 scanf 的原因了。
  • @Paul Tomblin:震惊!没有人使用scanf??为什么??这里到底发生了什么。我在这里错过了什么?
  • @walter 没有人使用 scanf 来处理人类的输入。
  • scanf 如果不能完全满足它的要求,它的表现就会不好。我认为在你的情况下发生的事情是它接受行尾的返回作为第一个字符第二个数组,然后从那里进入杂草,因为它不会这样做。

标签: c input scanf


【解决方案1】:

scanf() 之后添加getchar()

 for ( i = 0 ; i <= 2 ; i++ )
  { 
      printf ( "\nEnter name, price and pages: " ) ;
      k = scanf ( "%c %f %d", &b[i].name, &b[i].price, &b[i].pages ) ;

      getchar(); //will clear the buffer
  } 

PS:Don't use scanf() for char entry.

【讨论】:

    【解决方案2】:

    与其他说明符不同,%c 与 scanf 一起使用时不会忽略空格。在任何情况下,您都可能希望将名称字段设为字符串:

    #include <stdio.h>
    
    int main()
    { 
        struct book 
        { 
            char name[10] ;   // or some suitable size
            float price ; 
            int pages ; 
        } ;
    
        struct book b[3] ;
        int i ; int k;
        for ( i = 0 ; i <= 2 ; i++ )
        { 
            printf ( "\nEnter name, price and pages: " ) ;
            k = scanf ( "%s %f %d", b[i].name, &b[i].price, &b[i].pages ) ;
        } 
        for ( i = 0 ; i <= 2 ; i++ ) 
            printf ( "\n%s %f %d", b[i].name, b[i].price, b[i].pages ) ;
        return 0;
    }
    

    【讨论】:

      【解决方案3】:

      你可以在你的scanf前添加fflush(stdin);.

      事实证明,您不应该在stdin 上使用fflush,因为fflush被定义用于输出流。换句话说,fflush 在输入流上有未定义的行为。

      int fflush(FILE *ostream);
      

      C 标准的摘录说:

      ostream 指向输出流或 一个更新流,其中最 最近的操作没有输入, fflush 函数会导致任何未写入的 要交付的该流的数据 到要写入的宿主环境 到文件; 否则,行为 未定义。

      【讨论】:

      • 不,你不能 - fflush 只被定义为在输出流上工作。
      • fflush(stdin) 调用未定义行为。
      • 错误,虽然它可能有效:faq.cprogramming.com/cgi-bin/…
      • 当然,如果你可以调用 fflush(stdin);,但你是在冒险让恶魔飞出你的鼻子。 urbandictionary.com/define.php?term=nasal%20demons
      • @Paul Tomblin:似乎很清楚“行为未定义”意味着“错误”,除非您认为基于未定义行为编写程序是正确的。
      猜你喜欢
      • 2021-07-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-02
      • 2022-01-13
      • 1970-01-01
      • 2011-03-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多