Home > Software engineering >  creating a generic array taken from an array of structures
creating a generic array taken from an array of structures

Time:06-29

I need to pass to qsort a generic array. That array must be taken from the colons of a file structured like this: int,string,int,float. I've created an appropriate struct type but I'm having troubles creating a dinamically allocated array of structures.

here I created an array of pointers to structures

 struct *p_structure=malloc(n_records*sizeof(struct record_type*));

and then I have no idea on what to do :( Any help would be really appreciated, thanks

PS I calculated the n_records in advance

CodePudding user response:

I've created an appropriate struct type but I'm having troubles creating a dinamically allocated array of structures.

Assuming this is your struct:

struct record {
    int i1;
    char *s;
    int i2;
    float f;
};

This should be the array declaration:

struct record *array = malloc(sizeof(*array) * n_records);

and then I have no idea on what to do

In case you didn't do it already, you need to parse the file (see Appendix).

Once parsed, you have to define how your array items should compare against each another. In other words, what are the criteria that should be taken into consideration to compare (and of course, sort) your items. Programmatically, you need to provide a function that does that. That function's signature must match the signature of the function that qsort accepts as argument. For example (considering i1 as the comparison criteria):

int compare_record(const void *p1, const void *p2)
{
    const struct record *r1 = p1;
    const struct record *r2 = p2;

    if (r1->i1 > r2->i1)
        return 1;
    if (r1->i1 < r2->i1)
        return -1;
    return 0;
}

Now, calling qsort becomes straightforward:

qsort(array, n_records, sizeof(*array), compare_record);

Appendix

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct record {
    int i1;
    char *s;
    int i2;
    float f;
};

int compare_record(const void *p1, const void *p2)
{
    const struct record *r1 = p1;
    const struct record *r2 = p2;

    if (r1->i1 > r2->i1)
        return 1;
    if (r1->i1 < r2->i1)
        return -1;
    return 0;
}

int main(void)
{
    int n_records = 3;
    
    FILE *file = fopen("filename.txt", "r");
    if (!file) {
        printf("Opening file failed.\n");
        exit(EXIT_FAILURE);
    }
    
    struct record *array = malloc(sizeof(*array) * n_records);
    if (!array) {
        printf("An internal error has occurred.\n");
        exit(EXIT_FAILURE);
    }
    
    int index = 0;
    char line[1024]; // Large enough to hold a line?
    
    int i1, i2;
    float f;
    char s[256];
    
    while (fgets(line, sizeof line, file)) { // PS I calculated the n_records in advance 
        if (sscanf(line, "%d,%5[^\n,],%d,%f", &i1, s, &i2, &f) != 4) {
            // Problematic line...
            printf("Problematic line %d...\n", index 1);
        }
    
        array[index].i1 = i1;
        array[index].s = strdup(s);
        array[index].i2 = i2;
        array[index].f = f;
          index;
        
        printf("%d | %s | %d | %f\n", i1, s, i2, f);
    }
    
    fclose(file);
    
    qsort(array, n_records, sizeof(*array), compare_record);
    
    for (int i = 0; i < n_records;   i)
        printf("%d | %s | %d | %f\n", array[i].i1, array[i].s, array[i].i2, array[i].f);
    
    // Don't forget to free the memory allocated by strdup().
}

CodePudding user response:

It seems that you just created a structure pointer but you don't give it a variable name. Try this:

struct p_structure *your_var_name =malloc(n_records*sizeof(struct record_type*));

If it won't work, could you provide the code of your structures please ?

  • Related