简体   繁体   English

跳过 c 中的 scanf 循环

[英]skipping over scanf loops in c

I don't know why, when I run this, it skips the "how many pages in the book" scanf and goes straight onto the second loop "who is the author".我不知道为什么,当我运行它时,它会跳过“书中有多少页” scanf并直接进入第二个循环“谁是作者”。

I'm sure this is something to do with whitespace, but I thought I accounted for this with the getchar at the bottom of the for loop.我确定这与空格有关,但我认为我用 for 循环底部的getchar来解释这一点。

header:标题:

struct bookInfo{
  char title[40];
  char author[25];
  float price;
  int pages;
}; 

.c file: .c 文件:

int main()
{
  int ctr;
  struct bookInfo books[3]; 
  for (ctr = 0; ctr < 3; ctr++)
  {
    printf("what is the name of the book #%d?\n", (ctr+1));
    gets(books[ctr].title);
    puts("who is the author?");
    gets(books[ctr].author);
    puts("how much did the books cost");
    scanf(" $%f", &books[ctr].price);
    puts("how many pages in the book");
    scanf(" %d", &books[ctr].pages);
    getchar();
  }

  printf("here is the collection of books: \n");
  for (ctr = 0; ctr <3; ctr++)
  {
    printf("book #%d: %s by %s", (ctr+1), books[ctr].title, books[ctr].author);
    printf("\nit is %d pages and costs $%.2f", books[ctr].pages, books[ctr].price);
  }
  return 0;
}

Change this:改变这个:

puts("how much did the books cost");
scanf(" $%f", &books[ctr].price);

to this:对此:

printf("how much did the books cost: $");
fflush( stdout );
scanf("%f", &books[ctr].price);

Unless you intend for your user to type a $ before the price, which would be annoying.除非您打算让您的用户在价格前键入$ ,否则会很烦人。 You don't need the leading blank in the format string, since %f tells scanf to skip over leading whitespace.您不需要格式字符串中的前导空格,因为%f告诉scanf跳过前导空格。

Secondly, NEVER NEVER NEVER NEVER NEVER NEVER NEVER NEVER use gets .其次,永远永远永远永远永远永远永远永远永远永远不要使用gets Ever.曾经。 In any way, shape, or form.以任何方式,形状或形式。 It will (not might, will ) introduce a point of failure / major security hole in your program.(不是可能)在您的程序中引入故障点/主要安全漏洞。 It was deprecated in the 1999 standard, and has been removed from the standard library as of the 2011 standard.它在 1999 年标准中已被弃用,并已从 2011 年标准中的标准库中删除。 It is the programming equivalent of splicing live wires while standing in a shower.它相当于在淋浴时拼接火线的编程。

Use fgets (which, unlike gets , will attempt to store the newline character in the target buffer if there's room) or scanf (with an appropriate precision in the conversion specifier) instead.使用fgets (与gets不同,如果有空间,它将尝试将换行符存储在目标缓冲区中)或scanf (在转换说明符中具有适当的精度)。

That is because gets() reads the line of text present in the current buffer.那是因为 gets() 读取当前缓冲区中存在的文本行。 and since the current buffer contains "What is name of author ?"并且由于当前缓冲区包含“作者姓名是什么?” it reads it.它读取它。

If you display the contents of the struct members you can clearly observe this.如果您显示结构成员的内容,您可以清楚地观察到这一点。

So I Suggest this Use所以我建议这个用途

    char *temp;
    fgets(STDIN,temp);

before Loop begins.在循环开始之前。

This helps you这可以帮助你

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM