lsroudi
lsroudi

Reputation: 81

c iterate over an array

i have some issue with my code i read a file and i push the data inside the file into a struct data type

but when iterate over the dataValue which should be an array of struct it give me the same dataValue and specificly the last one in the file.

int main() {
    FILE *file;
    struct characteristic {
        double * dval;
        double n;
        char * name;
    };
    struct characteristic dataValue[150];
    if ((file = fopen("/XXX/XXX/XXX/XXX/data", "r"))
            == NULL) {
        puts("error reading file");
        exit(1);
    } else {
        int i = 0;
        double var1, var2, var3, var4;
        char * etiq = malloc(sizeof(char) * 100);
        while (fscanf(file, "%lf,%lf,%lf,%lf,%s \n", &var1, &var2, &var3, &var4,
                etiq) != EOF) {
            struct characteristic *new_node;
            new_node = (struct characteristic *) malloc(
                    sizeof(struct characteristic));
            new_node->dval = &var1;
            (new_node->dval)++;
            new_node->dval = &var2;
            (new_node->dval)++;
            new_node->dval = &var3;
            (new_node->dval)++;
            new_node->dval = &var4;
            new_node->name = etiq;
            puts("=================================================");

            printf("the name of characteristic number %d est : %s .\n", i,
                    new_node->name);
            dataValue[i].dval = new_node->dval;
            dataValue[i].name = new_node->name;
            dataValue[i].n = i;
            i++;
        }

    }
    int i,j;
    for (i = 0; i < sizeof(dataValue) / sizeof(struct characteristic); i++) {
        printf("second name of characteristic number %d est : %s .\n", i,
                dataValue[i].name);
        for (j = 0; j < 4; j++) {

            printf("bla value of vector number %d at index %d est : %lf \n", i,
                    j, *(dataValue[i].dval + j));
        }
    }
    return EXIT_SUCCESS;
}

the file containe data like : 1.0,2.7,4.9,1.5,name

Upvotes: 1

Views: 101

Answers (2)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726489

Your code is using an uninitialized pointer dval, and you are assigning it addresses of local variables that go out of scope before you print. This is not the way to create arrays in C.

You can allocate the array into dval by using malloc, but then you would have to free() that array as well. Since you know that there's going to be four doubles in the node, it would be simpler to make dval an array of four items, like this:

struct characteristic {
    double dval[4];
    double n;
    char * name;
};

Now you can do the assignments using either the pointer or the array syntax:

dataValue[i].dval[0] = var1;
dataValue[i].dval[1] = var2;
dataValue[i].dval[2] = var3;
dataValue[i].dval[3] = var4;
dataValue[i].n = i;
// Store etiq in the name, or make a copy:
dataValue[i].name = etiq;
// Prepare etiq for the next loop
etiq = malloc(100); // No need to multiply by sizeof(char)

Upvotes: 3

Manos Nikolaidis
Manos Nikolaidis

Reputation: 22224

You struct contains a pointer to double double *dval. It seems you intend to use it as an array of 4 doubles. But you are not allocating memory for 4 doubles. The recommended way to store 4 doubles in your struct would be to define an array inside it.

struct characteristic {
    double dval[4];
    double n;
    char * name;
};

There is a similar issue with the name. You allocate memory of 100 bytes once outside the while loop and obtain a pointer called etiq. Then for each element of dataValue you set name to the same pointer etiq to the same block that you are simply overwriting with fscanf. If you want a char* and not a char array in your struct use strdup to copy the string to a newly allocated memory block (and remember to free it independently from the struct). E.g.

new_node->name = strdup(etiq);

Or define name in your struct as char name[100] and either use strcpy or pass name directly to fscanf

Upvotes: 1

Related Questions