Calloc与fgets交互奇怪?

时间:2014-12-04 10:57:44

标签: c printf fgets

我的代码有问题。它应该以这种格式读取两个数字和一个句子:

no1
no2
sentence

并按照以下方式打印:

no1 no2 sentence

以下是代码:

scanf("%d", &nrP);
    for (i = 0; i < nrP; i++) {
        com[i].id = i;
        com[i].msg = calloc(256, 1);
        scanf("%d %f", &com[i].no1, &com[i].no2);
        fgets(com[i].msg, sizeof(com[i].msg), stdin);
        printf("%d\n", com[i].id);
        printf("\n%d %.6f ", com[i].no1, com[i].no2);
        printf("%s\n", com[i].msg);
    }

我已经包含了stdio.h和stdlib.h标头,并且还创建了com结构,但是决定不在这里发布它们以保持它更清洁。

所以对于这个数据输入:

15
12
I like c
21
23
But it is weird

应打印

1    
15 12 I like c
2
21 23 But it is weird    

但它打印

1
15 12 I l
2
0 0 ike

有什么想法吗? P.S:我需要为每个com [i] .msg。

分配确切的内存

1 个答案:

答案 0 :(得分:1)

明显的错误是传递指针com[i].msg的大小,其中指向块的大小应为fgets
(未读的非空白非数字后来会扫描数字。)

第二个错误是在scanf - 来电和fgets - 来电的输入错误测试中缺失。

第三个错误是缺少对calloc的检查 - 错误。

BTW:你为什么要使用calloc而不是malloc?您无法从执行的零初始​​化中获得任何优势,因为无论如何您都会立即覆盖它。

if(1 != scanf("%d", &nrP)) abort();
for (i = 0; i < nrP; i++) {
    com[i].id = i;
    if(!(com[i].msg = malloc(256))) abort();
    if(2 != scanf("%d %f", &com[i].no1, &com[i].no2)) abort();
    if(!fgets(com[i].msg, 256, stdin)) abort();
    printf("%d\n", com[i].id);
    printf("\n%d %.6f ", com[i].no1, com[i].no2);
    printf("%s\n", com[i].msg);
}
// You might want to replace `abort()` with whatever error-handling you prefer.