Reputation: 323
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));
Upvotes: 0
Views: 76
Reputation: 2896
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
#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
#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);
}
}
1
John Doe
[email protected]
1-555-456-7890
Upvotes: 1
Reputation: 1312
The idiomatic answer depends on whether or not you want consumers to treat your custom type as opaque or not. If it does not need to be opaque, use Mobius' advice, and move the full definition to the header.
Otherwise, you'll need to provide functions that return those members, e.g.:
char * client_tag_get_name(client_tag *t) {
return t->name;
}
and put the declaration for that in your header.
Upvotes: 1