首页 > 解决方案 > 用户输入被跳过

问题描述

仍然通过 C Programming Absolute Beginner's Guide。

我在关于结构的例子中,我无法弄清楚出了什么问题。当我编译并运行代码时,前两个问题运行良好,但在提示“这本书花了多少钱?”后,当我输入这个问题时,接下来的两个问题一起发布。我不知道为什么。我想我写的代码如书中所示。我在网上读到,gets 不是代码,但我现在不知道为什么。任何指导将再次不胜感激!

//This header file defines a structure for information about a book

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




/*This program gets the bookInfo structure by including structurePractice.h
and asks the user to fill in three structures and then prints them*/

//First, include the header file

#include "structurePractice.h"
#include <stdio.h>

int main()
{
    int ctr;
    struct bookInfo books[3]; //Array of 3 structure variables

    //Get information about each book from the user

    for (ctr = 0; ctr < 3; ctr++)
    {
        printf("What is the name of the book #%d?\n", (ctr+1));
        gets(books[ctr].title);
        puts("Who's is the author? ");
        gets(books[ctr].author);
        puts("How much did the book cost? ");
        scanf(" $%f", &books[ctr].price);
        puts("How many pages are in the book? ");
        scanf(" %d", &books[ctr].pages);
        getchar(); //Clears last newline for next loop
    }

    //Print a header line and then loop through and print the info

    printf("\n\nHere is the collection of books: \n");
    for (ctr = 0; ctr < 3; ctr++)
    {
        printf("#%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);
        printf("\n\n");
    }

    return (0);
}

标签: c

解决方案


你的scanf.

scanf(" $%f", &books[ctr].price);
        ^
        |
        here

这表示您想要 a$后跟一个十进制数。如果用户不输入美元符号,scanf 将不读取任何内容。输入将保留在输入缓冲区中。它将由下一个阅读scanf

这是许多问题scanf之一。因为scanf混淆了读取输入和解析输入,如果输入与预期格式不匹配,它将保留在输入缓冲区中。fgets相反,使用(not gets) 和.分别读取和解析sscanf。检查输入是否被读取也很重要,否则books[ctr].price将包含垃圾。

// Declare a buffer once outside the loop. Reuse it for each fgets call.
// BUFSIZ is a constant for the natural I/O buffer size of your platform.
char buf[BUFSIZ];

puts("How much did the book cost? ");
// Read only as much as the buffer can handle. This is what makes fgets safe,
// and gets unsafe.
fgets(buf, sizeof(buf), stdin);

// sscanf returns the number of items matched. Check if they all matched.
if( sscanf(buf, " %f", &books[ctr].price) != 1) {
    printf("Sorry, '%s' doesn't look like a price.", buf);

    // Set it to something or else it will be garbage.
    books[ctr].price = 0;
}

一个真正的程序会循环直到它得到有效的输入。重要的是读取缓冲区,然后解析它,并检查解析是否有效。稍后您可能会编写一个小函数来打包此提示代码。


推荐阅读