c - C 结构中的 float 成员不起作用:Code::blocks IDE 问题

标签 c

关闭。这个问题需要details or clarity .它目前不接受答案。












想改进这个问题?通过 editing this post 添加详细信息并澄清问题.

4年前关闭。




Improve this question




我不知道下面的程序有什么问题。它没有正确地输入结构成员。我正在使用 code::blocks 并且互联网上没有建议的解决方案似乎有效。所有建议都适用于 Turbo C 和 Borland C。请帮助大家。这是我的程序:

main()
{
    struct book
    {
        char name;
        float price;
        int pages;
    };
    struct book b[3];
    int i;
    for(i=0;i<3;i++)
    {
        printf("\n Enter name, price and pages: \t\t");
        scanf("%c %f %d",&b[i].name,&b[i].price,&b[i].pages);
    }
    for(i=0;i<3;i++)
    {
        printf("\n%c, %f, %d", b[i].name,b[i].price,b[i].pages);
    }
    getch();
}

最佳答案

初级问题 C 结构中的 float 成员不工作 ,是我们都知道的情况并非如此。问题是(与大多数使用 scanf 的新 C 程序员一样)最有可能是您的 scanf格式字符串。

在解决代码本身之前,有一些通用的有用提示。 启用编译器警告 (查看 Borland,Turbo 引用以了解在 Code::Blocks 中添加到编译器选项的内容)。我必须承认自 '91 或 '92 以来我没有使用过 Borland C,所以我手头没有编译器字符串选项。

将您的代码隔开,使其可读。年轻的眼睛可能对所有代码混合在一起没有问题,但对于其余的,一点间距会有所帮助。

一个现实世界的建议——永远不要使用浮点数作为货币。四舍五入会使钱消失(或出现)。
main 的两次有效调用是 int main (void)int main (int argc, char *argv[]) (并且有一些编译器允许的实现环境选项)

虽然您可以声明 struct bookmain() 内, 它的声明是本地的 main()意味着它不会在 main() 之外声明并且将无法用于可能需要帮助处理图书数据的任何功能。最好制作struc book全局声明。

自从一本书name通常有多个字符,(有超过 26 本书)您不太可能打算 char name; .更有可能您打算 name是一个可以保存完整书名的数组。最简单的解决方法是声明 name作为使用常量的固定长度数组(例如 #define MAXC 256 ... char name[MAXC]; ... )。

在您描述的数据上使用数组并将输入作为单行用户输入会暴露 scanf 的另一个问题。 . (如果标题中有空格,你如何告诉它标题的结尾?) 将调用分隔到 scanf在单独的电话中阅读书籍信息的每一位将有所帮助(留给您)。

最后,当你按下 Enter 时,你会生成一个 '\n'在输入缓冲区中。当您尝试阅读下一个 name , '\n'从前一个 Enter 保留在输入缓冲区中,%c格式说明符很乐意将其作为您的下一个字符。添加 " " (space) 在您的第一个格式说明符(如 chux 所述)之前,将消耗所有空格(换行符是空格),以便正确填充您的字符(或字符串)。

把它们放在一起,你可以做类似于以下的事情(你应该扩展):

#include <stdio.h>

#define NBOOKS 3        /* if you need a constant, define one (or more) */
#define MAXC 256

struct book {           /* struct book defined globally */
    char name[MAXC];    /* name declared as an array for multiple chars */
    float price;        /* never use floating-point for currency */
    int pages;
};

int main (void) {

    struct book b[NBOOKS] = {{ "", 0.0, 0 }};    /* initialize your struct */
    int i;

    for (i = 0; i < NBOOKS; i++) {
        printf ("\n Enter name, price and pages: \t\t");
        /* validate ALL user input */
        if (scanf (" %s %f %d", b[i].name, &b[i]. price,&b[i].pages) != 3) {
            fprintf (stderr, "error: invalid input.\n");
            return 1;
        }
    }
    putchar ('\n');
    for (i = 0; i < NBOOKS; i++) /* output books */
        printf ("%s, %f, %d\n", b[i].name, b[i].price, b[i].pages);

#if defined (__WIN32) || defined (__WIN64)
    getchar();  /* don't use getch(); it is 100% non-portable */
#endif

    return 0;
}

示例使用/输出
$ ./bin/bookstruct

 Enter name, price and pages:           book_1(no_spaces_in_name)  28.50 200

 Enter name, price and pages:           book_2 22.8 123

 Enter name, price and pages:           book_3 104.95 745

book_1(no_spaces_in_name), 28.500000, 200
book_2, 22.799999, 123
book_3, 104.949997, 745

( 注意: 如果您查看存储为 float 的价格,您可以直接了解为什么您不想使用浮点数作为货币)

如果您还有其他问题,请仔细查看并告诉我们。

评论跟进

当您开始想输入多字标题时,最好转用像 fgets 这样的面向行的输入功能。或 POSIX getline . 绝不,绝不,绝不使用 gets .它很容易出现缓冲区溢出,因此已从 C11 标准中删除。

面向行的输入函数的唯一技巧是读取(并包含)尾随 '\n'在他们填充的缓冲区中。它可以很容易地修剪。

然而,在使用面向行的方法进行 name 的多字阅读时,您现在需要使用 fgets 进行两次输入调用, 第一个为 name然后是 printpages .第二个缓冲区可以用 sscanf 解析分开pricepages ,例如
#include <stdio.h>
#include <string.h>

#define NBOOKS 3        /* if you need a constant, define one (or more) */
#define MAXC 256

struct book {           /* struct book defined globally */
    char name[MAXC];    /* name declared as an array for multiple chars */
    float price;        /* never use floating-point for currency */
    int pages;
};

int main (void) {

    struct book b[NBOOKS] = {{ "", 0.0, 0 }};    /* initialize your struct */
    int i;

    for (i = 0; i < NBOOKS; i++) {
        size_t len = 0;
        char buf[MAXC] = "";
        printf ("book[%d] enter name: ", i+1);
        /* validate ALL user input */
        if (!fgets (b[i].name, MAXC, stdin)) {
            fprintf (stderr, "error: invalid input for name.\n");
            return 1;
        }
        len = strlen (b[i].name);
        if (len && b[i].name[len-1] == '\n')
            b[i].name[len-1] = 0;

        printf ("book[%d] enter price & pages: ", i+1);
        if (!fgets (buf, MAXC, stdin)) {
            fprintf (stderr, "error: invalid input for price & pages.\n");
            return 1;
        }
        if (sscanf (buf, "%f %d", &b[i].price, &b[i].pages) != 2) {
            fprintf (stderr, "error: invalid input price & pages.\n");
            return 1;
        }
    }
    putchar ('\n');
    for (i = 0; i < NBOOKS; i++) /* output books */
        printf ("%-24s %7.2f     %d\n", b[i].name, b[i].price, b[i].pages);

#if defined (__WIN32) || defined (__WIN64)
    getchar();  /* don't use getch(); it is 100% non-portable */
#endif

    return 0;
}

示例使用/输出
$ ./bin/bookstruct
book[1] enter name: Tom Sawyer
book[1] enter price & pages: 23.95 287
book[2] enter name: Learning C Takes Time
book[2] enter price & pages: 521.99 10000
book[3] enter name: The Last Iceberg
book[3] enter price & pages: 290.19 385

Tom Sawyer                 23.95     287
Learning C Takes Time     521.99     10000
The Last Iceberg          290.19     385

查看新信息,如果您有任何问题,请告诉我。

关于c - C 结构中的 float 成员不起作用:Code::blocks IDE 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48333610/

相关文章:

c - 如何在纯 C 中进行正则表达式字符串替换?

c - 如何修复 ' Alrady print all array element of last row elements'

c - 将字符串解析为参数,然后连接其中的一些参数

c - 如何在基于 Debian 的发行版中找到某个文件所属的包?

c - C 中 uint32 的一维数组

c - 无法理解以下函数声明

C Keil 编译器使用 malloc 作为局部变量,为什么?

c - 如何在 C 中表示 float 的二进制乘法?

mysql - mysqldump如何将二进制数据写入文件进行MySQL逻辑备份?

c++ - 在 C++ 中声明长文字时是否需要长后缀和无符号后缀?