c- Странное поведение после получения входных данных
Я должен сделать программу, которая получает в качестве входных данных a и b, получает в качестве входных данных число "a" строк следующей формы: "studentId studentName studentPhone" и b строк ввода в виде "stId mark1 mark2 mark3 mark3". Затем программа выводит все данные из первого ввода, и если такой же идентификатор существует на входе b, программа выводит оценки учащихся, кроме своего идентификатора.
Я прошел через ад, чтобы получить ввод правильно, и я думаю, что это близко, но я получаю странное поведение: после того, как я ввел отметки во втором вводе, кажется, что некоторые из идентификаторов учеников в первом вводе изменены.
Это мой код: (здесь я пытаюсь ввести только идентификаторы студентов. 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 ответа
Проблема в
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));
Первая проблема заключается в неправильном распределении памяти (это может быть решением вашей проблемы, а может и нет), но это определенно то, что вы должны исправить).
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 символов? Я бы порекомендовал использовать другой способ чтения ввода, как описано здесь: Как читать с ввода, пока новая строка не будет найдена с помощью scanf()?
Вы должны выделить достаточно памяти для a
а также b
как
struct listA *a = malloc(sizeof(*a)* m);
struct listB *b = malloc(sizeof(*b) * n);
С вашим кодом вы размещаете соответствующим образом.