okay, ive searched a solution for like two days now but i couldnt find whats going wrong with my code. ;(
The task is simple: define a new type using typedef and have a function read out lines of this new type from a file into an array of again this new type. so my typedef inside the headerfile looks like this right now (ive tried several variants of writing this)
// filename: entries.h
#ifndef ENTRIES_H_
#define ENTRIES_H_
#include<time.h>
typedef struct{
char Loginname[25];
time_t RegDate;
unsigned long Highscore;
time_t Hdate;
}typePlayerEntry;
int readPlayerList(char *name, typePlayerEntry *feld);
#endif /* ENTRIES_H_ */
the main.c:
//filename: main.c
#include <stdio.h>
#include "entries.h"
int main(void) {
char name[13]="numbers.txt";
typePlayerEntry *pep;
readPlayerList(name, pep);
return 0;
}
my function file looks like this (and heres where the error is shown)
//filename: readPlayerList.c
int readPlayerList(char *name, typePlayerEntry *feld) {
return 0;
}
irrelevant code is completely left out. The problem is reproducable with the code posted.
the program wont compile because the type of the second argument in the function file could not be recognized,
- which is odd, because its defined in the header file and also usable in the main function.
And this error is somehow connected to the declaration of (in this case) a pointer of type playerEntry in my main.c. So if i do not declare it, theres no error, though i have to declare it to actually give it to the function. how come that the solution so far is to include the entries.h into the readPlayerList.c, which wasnt neccesary for previous functions?
im using eclipse kepler with MinGW, in case thats a compiler issue.
corrected the missing include of time.h and adjusted the code a little.
You are missing #include <time.h> in entries.h.
// filename: entries.h
#ifndef ENTRIES_H_
#define ENTRIES_H_
typedef struct {
char Loginname[25];
time_t RegDate; /* from <time.h> */
unsigned long Highscore;
time_t Hdate; /* from <time.h> */
} playerEntry;
int readPlayerList(char *name, playerEntry *feld);
#endif /* ENTRIES_H_ */
And you need to #include "entries.h" in readPlayerList.c
//filename: readPlayerList.c
int readPlayerList(char *name, typePlayerEntry *feld) {
/* ^^^^^^^^^^^^^^^ from entries.h */
return 0;
}
part of the problem is the compiler is seeing (at least) two different meanings/definitions for the 'playerEntry' name.
Suggest:
1) eliminate the 'typedef' statement
(it is just cluttering the code and confusing the compiler)
2) properly reference the struct via:
'struct playerEntry' instead of 'playerEntry'
in TheHeader.h file:
struct playerEntry
{
char Loginname[25];
time_t RegDate;
unsigned long Highscore;
time_t Hdate;
};
int readPlayerList(char *name, struct playerEntry *feld);
in the source file:
#include "TheHeader.h"
int readPlayerList(char *name, struct playerEntry *feld)
{
return 0;
}
Related
i´m trying to compile 3 files in C. One is main.c, where i declare the variables, another is cuenta.h and the other is cliente.h. cuenta.h has a struct used in another struct in cliente.h, but this error appears. How can I solve this? Thanks!
cliente.h
#ifndef PACABANK_CLIENTE_H
#define PACABANK_CLIENTE_H
#include "cuenta.h"
#include "fecha.h"
typedef struct {
char *dni;
char *titular;
Tarjeta tarjeta;
}InfoCliente;
cuenta.h
#ifndef PACABANK_CUENTA_H
#define PACABANK_CUENTA_H
#include "cliente.h"
#include "fecha.h"
typedef struct
{
int numero_tarjeta;
char *iban;
Fecha caducidad;
char *nombre_titular;
int cvv;
char *tipo; //mastercard, visa, american express.....
float limite;
}Tarjeta;
The error
In file included from cuenta.h:7:0,
from cuenta.c:5:
cliente.h:14:5: error: unknown type name 'Tarjeta'
Tarjeta tarjeta;
I need to build a "social network" for college, but I always get unknown type name 'List' while compiling. I removed a lot of functions from my headers, but I still get the same error and I don't know why.
I've got 3 headers:
My friend's header
#ifndef FRIEND_H
#define FRIEND_H
#include "ListHeadTail.h"
typedef struct Friend{
int id;
struct Friend *nextFriend;
}Friend;
void printFriends(List *l);
void removeFriend(List *l);
void addFriend(List *l);
#endif /* FRIEND_H */
My list header:
#ifndef LISTHEADTAIL_H
#define LISTHEADTAIL_H
#include "Student.h"
typedef struct pStudent{
struct pStudent *ant;
Student *s;
struct pStudent *prox;
}pStudent;
typedef struct list{
pStudent *head;
pStudent *tail;
}List;
void startList(List *l);
void printList(List *l);
void freeList(List *l);
#endif /* LISTHEADTAIL_H */
My student's header
#ifndef STUDENT_H
#define STUDENT_H
#define MAX 51
#include "Friend.h"
#include "ListHeadTail.h"
typedef struct Student{
int id;
char name[MAX];
Friend *friends;
}Student;
Student* readStudent ();
void printStudent(Student* a);
void changeData(List *l);
#endif /* STUDENT_H */
My main:
#include <stdio.h>
#include <stdlib.h>
#include "ListHeadTail.h"
#include "Friend.h"
#include "Student.h"
int main(int argc, char** argv) {
List l;
startList(&l);
freeList(&l);
return (EXIT_SUCCESS);
}
Thanks for reading.
Here's the (first) error I get when I try to compile this set of files:
$ cc main.c
In file included from main.c:4:
In file included from ./ListHeadTail.h:4:
In file included from ./Student.h:6:
./Friend.h:11:19: error: unknown type name 'List'
void printFriends(List *l);
Look at the file names and line numbers. Note that at ListHeadTail.h line 4, you've already defined LISTHEADTAIL_H, but you haven't yet reached the actual declaration of List. You then go into Student.h, and from there into Friend.h. That includes ListHeadTail.h again -- but since LISTHEADTAIL_H is already defined, this include does nothing. So you continue through Friend.h with no declaration of List, and therefore get an error on the declarations that reference it.
As noted by #lurker in their comment, the basic issue here is circular dependency, and a simple fix is forward declaration. In this case, you could simply modify Friend.H, replacing #include "ListHeadTail.h" with typedef struct list List;.
But to me this is a bit hacky. If you shift the order of includes somewhere, the build might break again.
I think the real problem is that the declarations of the functions (printFriends, etc.) don't belong in Friend.h; they belong in ListHeadTail.h. The functions have nothing to do with the Friend type. Sure, they have "Friend" in their names, but the only type referenced in the declarations is List. So they belong in ListHeadTail.h. Same goes for the changeData function in Student.h.
In an object-oriented design (say, in Java), these functions would all probably be methods of the List class, and would be declared in that class's source file.
I've been at this for several days now, unable to compile successfully. I made a very-oversimplified project separate from my main one. Depending which embeded struct I comment out, I get one of the following errors:
file: x2d_gfx_speech_balloon.h
error C2079: 'sprBalloon' uses undefined struct 'X2D_SPRITE'
error C2079: 'font' uses undefined struct 'X2D_FONT'
Side note: Putting the sprite and font headers from the common header into the speech balloon header itself has no effect either.
I'm going to provide the entire simplified code below. Please let me know if you see any syntax wrong, and optionally, feel free to compile it on your side if it helps. My environment is Windows 7 with Visual Studio 2010 and using C89.
main.c
#include "common.h"
int main(void)
{
return 0;
}
common.h
#ifndef _COMMON_H_
#define _COMMON_H_
#include <stdio.h>
#include <stdlib.h>
#include "constants.h"
#include "X2D_GFX_Sprite.h"
#include "X2D_GFX_Font.h"
#include "X2D_GFX_Speech_Balloon.h"
#endif
constants.h
#ifndef _CONSTANTS_H_
#define _CONSTANTS_H_
/* General Constants */
#define TRUE 1
#define FALSE 0
#endif
X2D_GFX_Font.h
#ifndef _X2D_GFX_FONT_H_
#define _X2D_GFX_FONT_H_
#include "common.h"
/* Font Structure */
struct X2D_FONT
{
float x, y;
int size;
int blnShow;
};
/* Font Prototypes (not shown here)... */
int fnt_init(struct X2D_FONT *objFont, const char *strFileName,
const char *strText, const float x, const float y,
const unsigned int size);
#endif
X2D_GFX_Font.c
#include "X2D_GFX_Font.h"
int fnt_init(struct X2D_FONT *objFont, const char *strFileName,
const char *strText, const float x, const float y,
const unsigned int size)
{
return TRUE;
}
X2D_GFX_Sprite.h
#ifndef _X2D_GFX_SPRITE_H_
#define _X2D_GFX_SPRITE_H_
#define MAX_VARSI 10
#include "common.h"
struct X2D_SPRITE
{
float x;
float y;
unsigned int width;
unsigned int height;
int blnShow;
float vx, vy;
float angle;
int varsi[MAX_VARSI];
};
int spr_init(struct X2D_SPRITE *spr, const char *strFileName);
#endif
X2D_GFX_Sprite.c
#include "X2D_GFX_Sprite.h"
int spr_init(struct X2D_SPRITE *spr, const char *strFileName)
{
return TRUE;
}
X2D_GFX_SPEECH_BALLOON.h
#ifndef _X2D_GFX_SPEECH_BALLOON_H_
#define _X2D_GFX_SPEECH_BALLOON_H_
#include "common.h"
/* Contains a list of acceptable balloon types */
enum ESpeechBalloonType
{
ESpeechBalloonType_Talk,
ESpeechBalloonType_Thought,
ESpeechBalloonType_Yell,
ESpeechBalloonType_Whisper
};
/* Speech Balloon types */
struct X2D_SPEECH_BALLOON
{
struct X2D_SPRITE sprBalloon;
struct X2D_FONT font;
enum ESpeechBalloonType eBalloonType;
};
#endif
X2D_GFX_SPEECH_BUBBLE.c
#include "X2D_GFX_SPEECH_BALLOON.h"
Your issue is the order in which files are included, specifically in X2D_GFX_Sprite.c. If you run just the preprocessor on that file (in Linux you can use cpp or gcc -E, I don't know how in Windows) and scroll down to the very end, you'll find that the X2D_SPRITE struct is being declared after it's used:
struct X2D_SPEECH_BALLOON
{
struct X2D_SPRITE sprBalloon;
struct X2D_FONT font;
enum ESpeechBalloonType eBalloonType;
};
# 11 "common.h" 2
# 7 "X2D_GFX_Sprite.h" 2
struct X2D_SPRITE
{
float x;
float y;
unsigned int width;
unsigned int height;
int blnShow;
float vx, vy;
float angle;
int varsi[10];
};
Two easiest ways to fix it would be to either not use common.h or move #include "common.h" after the struct declaration in X2D_GFX_Sprite.h.
This happens because X2D_GFX_Sprite.c includes X2D_GFX_Sprite.h, which includes common.h, which includes the other .h files. The preprocessor first copies in X2D_GFX_Sprite.h. When it finds #include "common.h", it begins copying that file. The first three includes are copied in. When it gets back to X2D_GFX_Sprite.h, it'll copy it in, but the header guards will get rid of everything in it. Next, it copies in X2D_GFX_Font.h and X2D_GFX_Speech_Balloon.h, which includes the X2D_SPEECH_BALLOON struct, in that order. Only then does it finally add in the rest of X2D_GFX_Sprite.h, including the X2D_SPRITE struct. This results in the two structs not being copied in the correct order.
File api.h
#include <stdio.h>
#ifndef API
#define API
struct trytag;
typedef struct trytag try;
void trial (try *);
#endif
File core.h
#ifndef CORE
#define CORE
struct trytag
{
int a;
int b;
};
#endif
File func.c
#include "api.h"
#include "core.h"
void trial (try *tryvar)
{
tryvar->a = 1;
tryvar->b = 2;
}
File main.c
#include "api.h"
int main ()
{
try s_tryvar;
trial(&s_tryvar);
printf("a = %d\nb = %d\n", s_tryvar.a, s_tryvar.b);
}
When I compile, I get:
main.c:5: error: storage size of ‘s_tryvar’ isn’t known
If I include core.h in main.c this error doesn't come as try is defined in core.h. But I want the structure try to be hidden to main.c — it should not know the members of try structure. What am I missing?
I don't think what you're trying to do is possible. The compiler needs to know how big a try structure is to compile main.c. If you really want it to be opaque, make a generic pointer type, and instead of declaring the variable directly in main(), make alloc_try() and free_try() functions to handle the creation and deletion.
Something like this:
api.h:
#ifndef API
#define API
struct trytag;
typedef struct trytag try;
try *alloc_try(void);
void free_try(try *);
int try_a(try *);
int try_b(try *);
void trial (try *);
#endif
core.h:
#ifndef CORE
#define CORE
struct trytag
{
int a;
int b;
};
#endif
func.c:
#include "api.h"
#include "core.h"
#include <stdlib.h>
try *alloc_try(void)
{
return malloc(sizeof(struct trytag));
}
void free_try(try *t)
{
free(t);
}
int try_a(try *t)
{
return t->a;
}
int try_b(try *t)
{
return t->b;
}
void trial(try *t)
{
t->a = 1;
t->b = 2;
}
main.c:
#include <stdio.h>
#include "api.h"
int main()
{
try *s_tryvar = alloc_try();
trial(s_tryvar);
printf("a = %d\nb = %d\n", try_a(s_tryvar), try_b(s_tryvar));
free_try(s_tryvar);
}
Think how the opaque FILE structure works in C. You only work with pointers, and you need a function like fopen() to create an instance, and a function like fclose() to dispose of it.
The problem is in main.c, the compiler hasn't seen the definition of struct try. Because of that, the compiler is limited to using pointers to struct try.
What you want to do is add two new functions to your API:
try *create_try();
void *destroy_try(try *t);
These functions will call malloc and free respectively.
If you don't want to limit your structure to only being allowed on the heap, you are going to have to give up on making it opaque.
There is a way to do something that technically is not exactly what you are asking for, but should serve the same purpose of keeping your structure opaque while supporting non-heap allocation.
in api.h, you state an opaque structure as follows:
struct trytag_opaque
{
char data[sizeof(int)*2];
};
if you wanted to be more opaque than that, you could calculate the maximum size of the structure required across any supported platform, and use:
struct trytag_opaque
{
char data[MAX_TRYTAG_SIZE];
};
Then your api.h function declarations would look like:
int try_a(struct trytag_opaque *t)
and your function code would look like:
int try_a(struct trytag_opaque *t_opaque) {
trytag *t = (trytag *)t_opaque;
...
}
and your main.c would look like:
#include "api.h"
int main() {
struct trytag_opaque t;
...
try_a(&t);
...
}
I have a header file port.h, port.c, and my main.c
I get the following error: 'ports' uses undefined struct 'port_t'
I thought as I have declared the struct in my .h file and having the actual structure in the .c file was ok.
I need to have the forward declaration as I want to hide some data in my port.c file.
In my port.h I have the following:
/* port.h */
struct port_t;
port.c:
/* port.c */
#include "port.h"
struct port_t
{
unsigned int port_id;
char name;
};
main.c:
/* main.c */
#include <stdio.h>
#include "port.h"
int main(void)
{
struct port_t ports;
return 0;
}
Many thanks for any suggestions,
Unfortunately, the compiler needs to know the size of port_t (in bytes) while compiling main.c, so you need the full type definition in the header file.
If you want to hide the internal data of the port_t structure you can use a technique like how the standard library handles FILE objects. Client code only deals with FILE* items, so they do not need (indeed, then generally can't) have any knowlege of what is actually in the FILE structure. The drawback to this method is that the client code can't simply declare a variable to be of that type - they can only have pointers to it, so the object needs to be created and destroyed using some API, and all uses of the object have to be through some API.
The advantage to this is that you have a nice clean interface to how port_t objects must be used, and lets you keep private things private (non-private things need getter/setter functions for the client to access them).
Just like how FILE I/O is handled in the C library.
A common solution that I use:
/* port.h */
typedef struct port_t *port_p;
/* port.c */
#include "port.h"
struct port_t
{
unsigned int port_id;
char name;
};
You use the port_p in function interfaces.
You will need to create special malloc (and free) wrappers in port.h as well:
port_p portAlloc(/*perhaps some initialisation args */);
portFree(port_p);
I would recommend a different way:
/* port.h */
#ifndef _PORT_H
#define _PORT_H
typedef struct /* Define the struct in the header */
{
unsigned int port_id;
char name;
}port_t;
void store_port_t(port_t);/*Prototype*/
#endif
/* port.c */
#include "port.h"
static port_t my_hidden_port; /* Here you can hide whatever you want */
void store_port_t(port_t hide_this)
{
my_hidden_port = hide_this;
}
/* main.c */
#include <stdio.h>
#include "port.h"
int main(void)
{
struct port_t ports;
/* Hide the data with next function*/
store_port_t(ports);
return 0;
}
It is generally no good to define variables in a header file.