Вопрос

I have to make a program that gets as an input a and b, gets as input a number "a" of lines of the following form: "studentId studentName studentPhone" and b lines of input in the form "stId mark1 mark2 mark3". The program then outputs all the stid from the first input and if the same id exists in input b the program outputs the students marks besides its id.

I've gone through hell to getting the input properly and I think this is close but I get a strange behavior: after I input the marks in the second input it seems like some of the student ids in the first input are changed.

This is my code: (here i try to input just the student IDs. 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;
}
Это было полезно?

Решение

The problem is in the

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

The result of m * sizeof(struct listA) is an integer, so when you put that into sizeof you get the size of the integer, not the number you want. You should change this to:

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

Другие советы

The first problem is that your memory allocation is wrong (this may be the solution to your problem or may be not, but it's definetly something you must fix).

Malloc is taking as parameter number of bytes of memory to allocate and returns a pointer to the allocated memory, or null if it has failed.

As you do now, struct listA *a = malloc(sizeof(*a));, you allocate space for an object (you have declared a as a pointer to an object and you alloc size of a's object bytes). You need to allocate memory for an array of objects, which has n*sizeof(*a) bytes, keeping the way you wrote it. You should check if malloc returns null.

Also, be careful that you may exceed the stPhone/stName/marks size.

It's a bad practice to use fflush, unless you really need it and especially on input streams: http://www.gidnetwork.com/b-57.html

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

Are you shure that a line with marks has at most 12 characters? I would recommend using another way of reading input, like described here: How to read from input until newline is found using scanf()?

You should allocate enough memory to a and b as

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

With your code you are allocating appropriately.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top