-2

I am struggling with getting my syntax correct when dynamically allocating an array of structs that I will then loop through and pass to a function which will populate the struct from a file. Any help would be much appreciated because I think I am misunderstanding two essential concepts 1. how to initially pass each struct in the array to the function 2. once in the function how to access and assign the value of the struct field.

This won't compile and these are the errors that I'm getting:

error: error: dereferencing pointer to incomplete type; 

for each of the three fields (name, age, weight)

warning: passing argument 2 of ârgetDogâ from incompatible pointer type [enabled by default] getDog(fp, dgy + i);



void getDog( FILE *fp, struct Dog *dgy ) 
{
    char dogName[21];
    double dogAge;
    double dogWeight;
    fscanf(fp, "%s%lf%lf", dogName, &dogAge, &dogWeight);
    strcpy(dgy->name, dogName);
    dgy->age = dogAge;
    dgy->weight = dogWeight;
}

int main( int argc, char *argv[] )
{

    FILE *fp = fopen( argv[ 1 ], "r" );
    
    // read in number of dogs
    int n;
    fscanf( fp, "%d", &n );

    struct Dog  {
    char name[21]; 
    double age;
    double weight;
    };
    
    struct Dog *dgy = (struct Dog *)malloc(n * sizeof(struct Dog));

    for (int i = 0; i < n; i++ ) {
        getDog(fp, dgy + i);
    }
    
    fclose(fp);
}
AVD
  • 111
  • 6
  • Does this compile? – Ed Heal Mar 14 '21 at 22:55
  • What specific error or incorrect behaviour are you observing? – kaylum Mar 14 '21 at 22:55
  • `dgy->age = &dogAge; dgy->weight = &dogWeight;` should be `dgy->age = dogAge; dgy->weight = dogWeight;` – kaylum Mar 14 '21 at 22:56
  • 2
    You can begin by moving your `struct Dog` declaration to outside of main. – anastaciu Mar 14 '21 at 22:56
  • @kaylum yes sorry I had actually already resolved that, let me update the post – AVD Mar 14 '21 at 22:57
  • Please be specific. Don't put "..." code. Do provide a [minimal verifiable example](https://stackoverflow.com/help/minimal-reproducible-example), do give specific errors and do ask a specific question. – kaylum Mar 14 '21 at 22:58
  • @EdHeal no it doesn't compile. – AVD Mar 14 '21 at 23:00
  • @kaylum thank you for the feedback, ill update! – AVD Mar 14 '21 at 23:00
  • @avd - Surely getting code to compile is the first port of call – Ed Heal Mar 14 '21 at 23:03
  • @EdHeal agree! that's what I am trying to achieve with this post. I think my misunderstanding of arrays of structures is keeping me from using the correct syntax – AVD Mar 14 '21 at 23:04
  • @anastaciu i think this was the problem! do structs always need to be declared outside of main? – AVD Mar 14 '21 at 23:07
  • 1
    Putt the `struct` at the top of the code. Get compiler to have all the warmings and take heed of those warnings – Ed Heal Mar 14 '21 at 23:08
  • 1
    Also `fopen` `fscanf` etc return values - check them. If in doubt check the manual pages – Ed Heal Mar 14 '21 at 23:10
  • thank you @EdHeal! moving struct resolved this and i have added additional checks to fopen and fscanf. really appreciate it i had been struggling with this for a few days and hadn't realized that struct needed to be declared elsewhere – AVD Mar 14 '21 at 23:12
  • 1
    @AVD well you can do it inside a function wether it's main or other, but then it will only be usable within the scope of that particular function. – anastaciu Mar 14 '21 at 23:12
  • @anastaciu that makes sense now thinking through it, this was my first time working with struct – AVD Mar 14 '21 at 23:13

1 Answers1

1

Please see comments below in the code

 // Some includes here - stdlib stdio

// This is needed for getDog
 struct Dog  {
    char name[21]; 
    double age;
    double weight;
 };
    

void getDog( FILE *fp, struct Dog *dgy ) 
{
//    char dogName[21]; Not required
//    double dogAge;
//    double dogWeight;

  // Check return value - ensure no buffer overrun
    if (fscanf(fp, "%20s%lf%lf", dgy->name, &dgy->age, &dgy->weight) != 3) {
       // Got an error - do summat about it
    }
//    strcpy(, dogName);  - Not required as fscanf does this for you
//    dgy->age = dogAge;
//    dgy->weight = dogWeight;
}

int main( int argc, char *argv[] )
{

    FILE *fp = fopen( argv[ 1 ], "r" );
    
// Is fp == NULL - if so error do summat about this
    // read in number of dogs
    int n;
    if ( fscanf( fp, "%d", &n ) != 1 ) {  // What is the point of || n < 1 ?
        invalidInput();
       // No point continuing to rest of code!
    }

    struct Dog *dgy = malloc(n * sizeof(struct Dog)); // Link below

    for (int i = 0; i < n; i++ ) {
        getDog(fp, dgy + i);
    }
    
    fclose(fp);
}
Ed Heal
  • 59,252
  • 17
  • 87
  • 127