Jasmine Jasmine - 5 days ago 4
C Question

Common C issue I cannot figure out: request for member in something not a structure or union

So I've made a struct to hold information about a Client. I get the compiler error stated as above in the title. I'm still learning pointers so bear with me if I state anything incorrect. From what I'm aware, my typedef has a pointer to an instance of Client. Which means I would need to use -> instead of . for fields of Client. But that didn't work either, I would get the error of

dereferencing to incomplete type
. Any guidance or help would be great!

Client.h

#ifndef CLIENT_H
#define CLIENT_H

typedef struct client_tag *Client;

#endif


Client.c

#include "client.h"


struct client_tag {
char id[5];
char name[30];
char email[30];
char phoneNum[15];
};


The following file reads client information from a file and assigns them to variables:

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

int main() {
Client client1 = malloc(sizeof(Client));
FILE *fp;
ListType clientList;

fp = fopen("clients.txt", "r");

int lineSize = 200;
char* line = malloc(lineSize);
char* line2 = malloc(lineSize);
char* line3 = malloc(lineSize);
char* line4 = malloc(lineSize);


while (fgets(line, lineSize, fp) != NULL) {
strcpy(client1.id, line);
strcpy(client1.name, fgets(line2, lineSize, fp));
strcpy(client1.email, fgets(line3, lineSize, fp));
strcpy(client1.phoneNum, fgets(line4, lineSize, fp));

push(clientList, (void*)&client1);

printf("ID: %s", line);
printf("Name: %s", line2);
printf("Email: %s", line3);
printf("Phone Number: %s\n", line4);

free(line);
free(line2);
free(line3);
free(line4);

line = malloc(lineSize);
line2 = malloc(lineSize);
line3 = malloc(lineSize);
line4 = malloc(lineSize);

}

}


Here is the error I get:

clientDriver.c: In function ‘main’:
clientDriver.c:23:17: error: request for member ‘id’ in something not a structure or union
strcpy(client1.id, line);
^
clientDriver.c:24:17: error: request for member ‘name’ in something not a structure or union
strcpy(client1.name, fgets(line2, lineSize, fp));
^
clientDriver.c:25:17: error: request for member ‘email’ in something not a structure or union
strcpy(client1.email, fgets(line3, lineSize, fp));
^
clientDriver.c:26:17: error: request for member ‘phoneNum’ in something not a structure or union
strcpy(client1.phoneNum, fgets(line4, lineSize, fp));

Answer

I believe the problem is that you can't used fields on a client_tag or client_tag * if you don't have the declaration for client_tag in your header file.

My recommendation would be to move the struct declaration for client_tag from client.c to client.h

Based on the above instructions, The following code compiles and runs

client.h

#ifndef CLIENT_H
#define CLIENT_H

struct client_tag {
    char id[5];
    char name[30];
    char email[30];
    char phoneNum[15];
};

typedef struct client_tag *Client;

#endif

main.c

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

/* Minimal list implementation
 * Based on functions in your program
 */
typedef struct {
  unsigned length;
  size_t allocated_size;
  void ** items; 
} ListType;

/* Push implemented based on the usage in your code */
int push(ListType l, void* item){
  // check if we need to allocate memory
  if (l.length >= l.allocated_size){
    size_t next_size = (l.allocated_size > 0) ? l.allocated_size * 2 : sizeof(void*);
    l.items = (void **) realloc(l.items, next_size);
    if (l.items == NULL){
      return -1; // error
    }

    l.allocated_size = next_size;
  }

  // push the item;
  l.items[l.length++] = item;
  return l.length;
}

int main() {
    Client client1 = malloc(sizeof(Client));
    FILE *fp;
    ListType clientList;

    fp = fopen("clients.txt", "r");

    int lineSize = 200;
    char* line = malloc(lineSize);
    char* line2 = malloc(lineSize);
    char* line3 = malloc(lineSize);
    char* line4 = malloc(lineSize); 


    while (fgets(line, lineSize, fp) != NULL) { 
        strcpy(client1->id, line);
        strcpy(client1->name, fgets(line2, lineSize, fp));
        strcpy(client1->email, fgets(line3, lineSize, fp));
        strcpy(client1->phoneNum, fgets(line4, lineSize, fp));

        push(clientList, (void*)&client1);

        printf("ID: %s", line);
        printf("Name: %s", line2);
        printf("Email: %s", line3);
        printf("Phone Number: %s\n", line4);

        free(line);
        free(line2);
        free(line3);
        free(line4);

        line = malloc(lineSize);
        line2 = malloc(lineSize);
        line3 = malloc(lineSize);
        line4 = malloc(lineSize);

    }

}

clients.txt

1
John Doe
john.doe@example.com
1-555-456-7890