【问题标题】:c- Strange behavior after getting inputsc- 获得输入后的奇怪行为
【发布时间】:2013-11-23 17:32:55
【问题描述】:

我必须制作一个程序,将 a 和 b 作为输入,将以下形式的行数“a”作为输入:“studentId studentName studentPhone”和 b 行以“stId mark1 mark2”的形式输入标记 3"。然后程序从第一个输入中输出所有 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;
}

【问题讨论】:

  • a不是数组,那你为什么用a[i]
  • 您使用的是 MS Windows 吗?你使用的是哪个编译器?
  • 我忘记将 sizeof 与 m 和 n 相乘,所以它们都是数组。我只是这样做了,在我获得第二个输入后它仍然会更改第一个输入的值
  • @hacks 我在 Windows 上,但我在 ideone.com 上运行它(查看链接)
  • 使用fflush(stdin);(MS DOS 除外)将调用未定义的行为。

标签: c input scanf gets


【解决方案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));

【讨论】:

    【解决方案2】:

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

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

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

    另外,请注意您可能会超出 stPhone/stName/marks 的大小。

    除非你真的需要它,尤其是在输入流上,否则使用 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()?

    【讨论】:

    • 不能超过 12 个字符,因为最多 3 个标记可以是最多 100 个,包括不能超过 12 个的空格。stPhone 和 stName 也是如此
    【解决方案3】:

    你应该为ab分配足够的内存

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-09
      • 2011-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多