2013-11-11 3 views
0

Мне нужно сделать программу, которая поступает как вход a и b, получает в качестве ввода число «a» строк следующей формы: «studentId studentName studentPhone» и b строк ввода в форме «stId mark1 mark2 mark3». Затем программа выводит все стили с первого входа, и если один и тот же идентификатор существует на входе b, программа выводит метки учащихся, кроме своего идентификатора.c- Странное поведение после получения входов

Я прошел через ад, чтобы получить вход правильно, и я думаю, что это близко, но я получаю странное поведение: после ввода меток во втором входе кажется, что некоторые из идентификаторов студента в первом вводе изменилось.

Это мой код: (здесь я пытаюсь ввести только идентификаторы студентов 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; 
} 
+0

'a' не является массивом, то почему вы используете' a [i] '? – Shubham

+0

Вы на MS Windows? И какой компилятор вы используете? – haccks

+0

Я забыл умножить sizeof на m и n, чтобы они оба были массивами. Я просто сделал это, и он все еще меняет значения первого ввода после того, как я получу второй вход – Arlind

ответ

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)); 
0

Вы должны выделить достаточно памяти для a и b в

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

С вашего кода вы выделяя соответственно.

1

Первая проблема заключается в неправильном распределении памяти (это может быть решением вашей проблемы или может быть не так, но это определенно то, что вы должны исправить).

Malloc берет в качестве параметра количество байтов памяти для выделения и возвращает указатель на выделенную память, или null, если он сработал.

Как вы теперь делаете, struct listA *a = malloc(sizeof(*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()?

+0

Не может быть более 12 символов, так как те не более 3 знаков могут быть не более 100 и включать пробелы, которые он не может больше, чем 12. То же самое касается stPhone и stName – Arlind

Смежные вопросы