Okay, I have a main source called main.c, a header file called test.h, and another class called handBeraknare.c.
Im trying to make my code a bit more readable by transfeering some of my methods to the class handBeraknare.c.
So in main.c i have a struct that looks like this:
typedef struct kort{
int draget;
char farg;
int nummer;
struct kort *next;
}kort; `
In main.c i create a couple of these using kort k=(kort*)malloc(sizeof(kort)); and put them into an array. What im trying to achive is to send this array of kort to a function in handBeraknare.c but I get some sort of weird error "in file included from handBeraknare.c".
Im gussing this has to do with the headerfile now knowing what "kort" is (my struct). Anyway, here's some of the code:
// in test.h
int beraknaFarg(kort kortHand[]);
// in handBeraknare.c
#include <stdio.h>
#include "test.h"
int beraknaFarg(kort kortHand[]){
char c = kortHand[0].farg;
int i;
for (i=1;i<5;i++){
if (kortHand[i].farg!=c){
printf("inte färg");
system("pause");
//Spelaren har inte färg. Retunera 0
return 0;
}
}
//Spelaren har färg. Retunera 1
printf("!!!!färg");
system("pause");
return 1;
}
//part of the main class. Calling function test()
// which calls the method beraknaHand which exists in handBeraknare.c
#include "test.h"
...
int main(int argc, char *argv[])
{
test();
}
// the testfunction in my mainclass
void test(){
char farg[4]={'S','K','R','J'};
int nummer[14]={0,2,3,4,5,6,7,8,9,10,11,12,13,14};
kort kortArray[52];
kort kortHand[5];
kort *k;
k=(kort*)malloc(sizeof(kort));
k->farg='s';
k->nummer=5;
kortHand[0]=*k;
k->farg='s';
k->nummer=11;
kortHand[1]=*k;
k->farg='s';
k->nummer=12;
kortHand[2]=*k;
k->farg='s';
k->nummer=11;
kortHand[3]=*k;
k->farg='s';
k->nummer=9;
kortHand[4]=*k;
beraknaFarg(kortHand);
Make test.h to read
typedef struct kort{
int draget;
char farg;
int nummer;
struct kort *next;
} kort;
int beraknaFarg(kort kortHand[]);
and remove the typedef from main.c
You need to define the typedef in the header file, and then include the header file in the C file you want it to use it.
in addition , because it is typedef defintion and not declaration , you need to define it in the C file.
I.E
h file:
typedef strcut
{
int a;
....
}t_struct_type;
c file:
t_struct_type struct_var;
if you want to use struct_var in more than one c file , you need to add the extern keyword in the h file. like this : extern t_strcut_type struct_var
Related
this a reproducible example and not the entire code the entire code is too large..
my problem was that i had a structure that i created using malloc and i needed to access it from another function in another file, but i keep getting segfault...
header file
main.h
#ifndef main_a
#define main_a
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct cmd_s
{
int n;
} cmd_t;
extern cmd_t *ptr;
void push(char *line);
#endif
the main.c file
main.c
#include "main.h"
cmd_t *ptr = NULL;
int main(void)
{
cmd_t *ptr = malloc(sizeof(cmd_t));
ptr->n = 5;
push("line");
return (0);
}
and where i need to access the struct from named opcode.c
opcode.c
#include "main.h"
void push(char *line)
{
int new = ptr->n;
}
note that this is not the actual code the actual code has useful values, this is an example that contains the challenge i am facing
i tried to use static instead but i got the same error.
i'm still a novice in c programming..
and i don't want to change the way i created the structure, which is through malloc because another function depends on it... i just need to make that malloced structure accessible to another file in the program.
thanks.
int main(void)
{
cmd_t *ptr = malloc(sizeof(cmd_t));
You create new ptr variable visible only in function main. Your push see the global pointer ptr but not the one you have malloced.
You need to
int main(void)
{
ptr = malloc(sizeof(*ptr));
/* .... */
Use obiects not types in sizeof (as in this example)
i'm doing a simple project in C in which, for the moment, i use two structs: Player and Card.
I have created the 2 struct in different header files, because functions in Player use Card, but also other elements that I haven't already done.
When I try to use getId() in Player, the VSCode's compiler says:
reference to external symbol _getId not resolved in _discardCard()
card.h code is:
#include <stdbool.h>
typedef struct card{
int id;
bool black;
int numElems;
char* text[3];
}card;
card* initCard(int id,bool black,char* text[],int numElems)
int getId(card* c);
card.c code is:
#include "carta.h"
#include<stdio.h>
#include <stdbool.h>
#include <stdlib.h>
...
int getId(carta* c){
return c->id;
}
Instead the code for Player.h is:
#include "card.h"
#define CARDSMAX 5
typedef struct{
bool master;
int id;
int points;
char* nickname;
card* cards[CARDSMAX];
int NumCards;
}player;
... //other functions
card* discardCard(int id,player* g);
The code for Player.c is:
#include "player.h"
#include <stdio.h>
#include <stdlib.h>
player* initPlayer(char* nickname,int id){
player* g=(player*) malloc(sizeof (player));
g->id=id;
g->nickname=nickname;
g->master=false;
g->points=0;
g->NumCards=0;
for(int i=0;i<CARDSMAX;i++){
g->cards[i]=(card*)malloc(sizeof(card));
}
return g;
}
....
card* DiscardCard(int id,player* g){
for(int i=0;i<CARDSMAX;i++){
card* c=g->cards[i];
if(getId(c)==id){
card* e= g->cards[i];
g->cards[i]=NULL;
g->NumCards--;
return e;
}
}
return NULL;
}
Can someone help me? (If you see some inconsistency in the code, it'is because i tried a fast translation from my language)
So, as suggested , the problem was that in Windows' compiler, when you use struct that use function defined in other structs,it is required to pass the .obj file during the compilation .
For doing this you need to compile every .c file that is used by others singulary and then link the .obj file created in this fase.
So in my case the first step is to compile:
cl card.c
that create a card.obj (the Windows' compiler could show you a message that says something like:"The start point is not indicated" if you don't use a main in this first file, don't worry and carry on with this procedure) and then I compile:
cl player.c /link card.obj
So in this way you pass the compiled object in which it's provided the implementation of all the function in the struct.
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.
The struct declaration in my main.c file. I have the function prototype declared but not shown.
typedef struct data
{
int t;
float tp, tf, tt;
} reactorData;
int main()
{
reactorData reactorOne[21];
//other stuff
}
This is the function giving me errors in my function.c file. Specifically in the printf() statement.
typedef struct data reactorData; //this is what I have up top
void reactorOutput(reactorData * data)
{
int c;
for (c=0;c<21;c++)
{
printf(" %3d\t %.0f\t %.0f\t %.0f\n",c, data[c].tp, data[c].tf, data[c].tt);
}
}
The error reads:
|error: invalid use of undefined type 'struct data'|
The function itself works perfectly fine/ I've tested it within main. Its only when I have it in functions.c it doesn't work.
New structs and type definition that must be shared across different compile units are best placed in a header file:
// mystructh.h
#ifndef MYSTRUCT_H
#define MYSTRUCT_H
typedef struct data
{
int t;
float tp, tf, tt;
} reactorData;
void reactorOutput(reactorData * data);
// other stuff
#endif
then in the other c files you have to include the header
main.c
#include <stdio.h>
#include "mystruct.h"
int main(void)
{
reactorData reactorOne[21];
// for example
reactorOutput(reactorOne);
//other stuff
}
functions.c
// functions.c
#include "mystruct.h"
void reactorOutput(reactorData * data)
{
int c;
for (c=0;c<21;c++)
{
printf(" %3d\t %.0f\t %.0f\t %.0f\n",c, data[c].tp, data[c].tf, data[c].tt);
}
}
The problem with your version is that struct data is only defined in main.c.
When the compiler compiles functions.c, it doesn't know what struct data is.
That's why you have to use header files live shown above.
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);
...
}