c-获得输入后的奇怪行为

时间:2013-11-11 19:37:26

标签: c input scanf gets

我必须制作一个作为输入a和b的程序,输入以下形式的数字“a”的数字:“studentId studentName studentPhone”和b行输入形式“stId mark1 mark2 MARK3" 。程序然后从第一个输入输出所有stid,如果输入b中存在相同的id,程序将输出除其id之外的学生标记。

我已经通过地狱来正确获取输入并且我认为这很接近但我得到一个奇怪的行为:在我输入第二个输入中的标记后,似乎第一个输入中的一些学生ID被更改。

这是我的代码:(这里我尝试只输入学生ID。http://ideone.com/dBYzwe

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>


void chomp(char *s);

struct listA{
    int stId;
    char stName[19];
    char stPhone[12];

    };

struct listB{
    int stId;
    char marks[11];

};


int main(void) {
    int i, j, m, n;

    scanf("%d%d", &m, &n);

struct listA *a = malloc(sizeof(m * sizeof(struct listA)));
    struct listB *b = malloc(sizeof(n * sizeof(struct listB)));

    for(i = 0; i < m; i++)
    {
        scanf("%d", &a[i].stId);
        fgets(a[i].stName, 19, stdin);
        fgets(a[i].stPhone, 11, stdin);
        chomp(a[i].stName);
        chomp(a[i].stPhone);

    }
    for(i = 0; i < m; i++)
            printf("%d ", a[i].stId);


    for(i = 0; i < n; i++)
    {
        scanf("%d ", &b[i].stId);
        fgets(b[i].marks, 12, stdin);
        fflush(stdin);
    }

    printf("\n");


        for(i = 0; i < n; i++)
    {
        printf("%d ", b[i].stId);
    }


    printf("\n");

    for(i = 0; i < m; i++)
            printf("%d ", a[i].stId);




    return 0;









}
void chomp(char *s) {
    while(*s && *s != '\n' && *s != '\r') s++;

    *s = 0;
}

3 个答案:

答案 0 :(得分:1)

问题在于

struct listA *a = malloc(sizeof(m * sizeof(struct listA)));
struct listB *b = malloc(sizeof(n * sizeof(struct listB)));

m * sizeof(struct listA)的结果是一个整数,所以当你把它放到sizeof时,你会得到整数的大小,而不是你想要的数字。您应该将其更改为:

struct listA *a = malloc(m * sizeof(struct listA));
struct listB *b = malloc(n * sizeof(struct listB));

答案 1 :(得分:1)

第一个问题是你的内存分配是错误的(这可能是你的问题的解决方案,或者可能不是,但你必须解决这个问题)。

Malloc将参数作为分配的内存字节数并返回指向已分配内存的指针,如果失败则返回null。

正如您现在所做的那样,struct listA *a = malloc(sizeof(*a));,您为对象分配空间(您已声明一个指向对象的指针,并且您分配了一个对象字节的大小)。您需要为对象数组分配内存,该数组具有n * sizeof(* a)字节,保持您编写它的方式。您应该检查malloc是否返回null。

另外,请注意,您可能会超过stPhone / stName /标记大小。

使用fflush是一种不好的做法,除非你真的需要它,特别是输入流:http://www.gidnetwork.com/b-57.html

fgets(b[i].marks, 12, stdin);

您是否确定带有标记的行最多包含12个字符?我建议使用另一种阅读输入的方式,如下所述:How to read from input until newline is found using scanf()?

答案 2 :(得分:0)

您应该为ab分配足够的内存作为

struct listA *a = malloc(sizeof(*a)* m);
struct listB *b = malloc(sizeof(*b) * n);

使用您的代码进行适当分配。