I am stuck on (what i think is) a circular dependency problem in VS2017 coding in c.
I tried looking up the problem, and found a lot of similar problems on stackoverflow, but I can't seem to get my problem solved with those questions.
My code:
main.c
#include <stdio.h>
#include "travelers.h"
#include "trip.h"
int main(void) {
int nTravelers = 0;
int nTrips = 0;
Traveler *travelersArray = (Traveler*)calloc(nTravelers, sizeof(Traveler));
Trip *tripsArray = (Trip*)calloc(nTrips, sizeof(Trip));
return 0;
}
travelers.h
typedef struct {
unsigned int id;
char *name;
char *adress;
char *residence;
} Traveler;
trip.h
typedef struct {
unsigned int id;
char *touringCar;
char *destination;
char *date;
Traveler *travelers;
unsigned int amount;
} Trip;
the travelers.c and trip.c files are only contain #include "travelers.h"/#include "trip.h"
The error occurs only in trip.h at Traveler *travelers;:
I don't know how to resolve this.
This looks like the same problem, but I couldnt translate it to my code.
Any help is apriciated.
No cycles here.
If trip.c includes trip.h is shall also include travelers.h as its definitions (Trip) depends on the latter (Traveller).
Knowing this, one could include travelers.h into trip.h. Still, this complicates things, so it is a good idea to 1st of all add to every header so call header-guards, protecting against duplicate definitions on pre-processor level.
Doing so made the headers look like this:
travelers.h
#ifndef TRAVELERS_H
#define TRAVELERS_H
typedef struct {
unsigned int id;
char *name;
char *adress;
char *residence;
} Traveler;
#endif // #ifndef TRAVELERS_H
trip.h
#ifndef TRIP_H
#define TRIP_H
#include "travelers.h" // makes including it unnecessary where trip.h is included
typedef struct {
unsigned int id;
char *touringCar;
char *destination;
char *date;
Traveler *travelers;
unsigned int amount;
} Trip;
#endif // #ifndef TRIP_H
As a remark, the error is caused by the typedef. C accepts opaque structs provided you do not need their implementation details:
a.h:
struct A {
int aVal;
const char * astr;
};
a.c:
#include "a.h"
const char *getAStr(struct A*a) {
return a->astr;
}
b.h
const char *getName(struct B*);
struct B {
int bVal;
struct A *a;
};
b.c
#include "b.h"
const char *getAStr(struct A*);
const char * getName(struct B* b) {
return getAStr(b->a);
}
main.c
#include <stdio.h>
#include "a.h"
#include "b.h"
int main() {
struct A a = { 1, "foo" };
struct B b = { 2, &a };
printf("%d - %d : %s\n", b.bVal, b.a->aVal, getName(&b));
return 0;
}
compiles and links without even a warning while in b.c nothing is known on struct A except that it is a struct.
Related
I created a structure item:
typedef struct item
{
char name[20];
char desc[100];
int lp;
int shield;
int weapon;
} item;
I need 36 of them so I create an array item treasure[6][6];
For each item I insert the data as so:
strcpy(treasure[0][0].name, "name");
strcpy(treasure[0][0].desc, "none");
treasure[0][0].lp = 0;
treasure[0][0].shield = 0;
treasure[0][0].weapon = 200;
I do this 36 times and takes a lot of space in editor, my question: Can I put this in a separate .c/.h file maybe? I've been trying to but can't make it work.
Thanks for any help!
I suggest that use a file, like init.h with the following content
#include <string.h>
typedef struct item {
char name[20];
char desc[100];
int lp;
int shield;
int weapon;
} item;
item treasure[1][1] = {
{{.name = "name", .desc = "none", .lp = 0, .shield = 0, .weapon = 200}}};
In that way you must be able to initialize the struct of you matrix 6, 6 in another file, then you must be able to access it from the main program calling it like this:
#include "init.h"
#include <stdio.h>
int main() {
printf("%s\n", treasure[0][0].name);
return 0;
}
I hope this work for you, there a another ways to initialize structs, but this one is what I use more often. You can find more information here
https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html
If you want to learn how to do proper C program design from the start, then this is how.
The correct way to do this is to create an item.h and a item.c file. Together they form a "code module" (or class, if you will).
Your header file item.h should contain the typedef and header guards. You should write an initialization function too.
// item.h
#ifndef ITEM_H
#define ITEM_H
#include <string.h>
typedef struct {
char name[20];
char desc[100];
int lp;
int shield;
int weapon;
} item_t;
void item_init (item_t* item,
const char name[20],
const char desc[100],
int lp,
int shield,
int weapon);
#endif
You can then implement the init function in init.c:
// item.c
#include "item.h"
void item_init (item_t* item,
const char name[20],
const char desc[100],
int lp,
int shield,
int weapon)
{
strcpy(item->name, name);
strcpy(item->desc, desc);
item->lp = lp;
item->shield = shield;
item->weapon = weapon;
}
These two files, init.h and init.c are only concerned about the behavior of all item_t variables. You can expand them with more functions as you go. They do not and should not contain any actual data.
Now if you want to keep the data separate, you could create a separate pair of files for it like this:
// item_data.h
#include "item.h"
#define ITEMS_N 36
item_t* item_data_get (int item_n);
This is just a "getter" function that lets you access the data. The actual data is encapsulated in the .c file:
// item_data.c
#include "item_data.h"
static item_t items [ITEM_N] =
{
[0] = {.name="name", .desc="none", .lp=0, .shield=0, .weapon=200},
[1] = ... // fill up data here
};
item_t* item_data_get (int item_n)
{
return items[n];
}
If you later on want to change the data of a given item, you can do so by calling item_init(item_data_get(n), ...);
for the past few months I've been trying to code in pure C and avoid C++ as much as I can (for personal reasons, C++ is a nice language in deed), but once in a while there comes situations where I miss some concepts that I used to be using a lot back when I coded in C++, which there is no obvious equivalent in C for them, one of those concepts being "Interface". so after a few hours of research I came up with this solution but I'm afraid that my code might go wrong sometime in the future. Below is the sample code of what I want to do:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
typedef int (*on_affected_cb) (const char *msg);
typedef struct affectee_t affectee_t;
typedef struct type_a_t type_a_t;
typedef struct type_b_t type_b_t;
typedef struct type_c_t type_c_t;
typedef struct owner_t owner_t;
//******************************************************************************
struct affectee_t{ //interface
on_affected_cb on_affected;
};
void affectee_notify(affectee_t* self, const char* msg){
self->on_affected(msg);
}
//******************************************************************************
struct type_a_t{ //implementor a
affectee_t affectee;
int num;
};
static int type_a_on_affected (const char *msg){
printf("this is type a reading msg: %s\n", msg);
return 1000;
}
void type_a_init(type_a_t* self){
self->num = 0;
self->affectee.on_affected = type_a_on_affected;
}
//******************************************************************************
struct type_b_t{ //implementor b
affectee_t affectee;
char name[128];
};
static int type_b_on_affected (const char *msg){
printf("this is type b reading msg: %s\n", msg);
return 2000;
}
void type_b_init(type_b_t* self){
memset(self->name, 0, sizeof(self->name));
self->affectee.on_affected = type_b_on_affected;
}
//******************************************************************************
struct owner_t{ // ordinary struct/class
type_a_t ta;
type_b_t tb;
};
void owner_init(owner_t* self){
type_a_init(&self->ta);
type_b_init(&self->tb);
}
void owner_notify(owner_t* self){
const char msg[] = "what the f...!";
affectee_notify((affectee_t*)&self->ta, msg); //<- pointer casting!!!
affectee_notify((affectee_t*)&self->tb, msg); //<- same here
}
//******************************************************************************
int main(int argc, char **argv){
owner_t owner;
owner_init(&owner);
owner_notify(&owner);
}
I'm trying to define a struct in a header file with function prototypes that take pointer to that struct as a parameter.
#ifndef _GETDATA
#define _GETDATA
struct PERSONDATA{
char name[20];
double age,mass;
};
typedef struct PERSONDATA person;
extern void getData(person *);
extern void getName(char *,int);
#endif
The getData.c file is defined as such;
#include <stdio.h>
void getData(person *ptr)
{
printf("Enter name: ");
getName(ptr->name,sizeof(ptr->name));
}
and the getName.c file is defined as:
#include <stdio.h>
void getName(char *ptrName, int varSize)
{
int i=0;
do
{
*(ptrName++) = getchar();
++i;
if(i==varSize) printf("array full, EXITING!\n");
}while(*(ptrName-1)!='\n' && i<varSize);
}
Lastly, the main function was:
#include <stdio.h>
#include "GETDATA.h"
int main(int argc, char **argv)
{
person human1;
printf("hello, world!\n\n");
getData(&human1);
return 0;
}
On compiling the program, I get the following error:
***C:/Users/Shoaib.Shoaib-PC/Google Drive/C workspace/C workspace codelite/StructPointerExample/getData.c:2:14: error: unknown type name 'person',
void getData(person *ptr)***
Could some one please help me out here, any help is greatly appreciated!
You should include the header file in ALL files using the declared types, not just in the main file.
I am trying to declare a struct and use it in multiple files and I am getting an error that I cannot figure out. Sample code is posted below.
in test.h
#ifndef TEST_H
#define TEST_H
struct mystruct;
struct mystruct *new_mystruct();
void myprint(struct mystruct*,int);
#endif
int test.c
#include "test.h"
#include <stdio.h>
#include <stdlib.h>
struct mystruct {
int *myarray;
};
struct mystruct *new_mystruct(int length)
{
int i;
struct mystruct *s;
s = malloc(sizeof(struct mystruct));
s->myarray = malloc(length*sizeof(int));
for(i = 0; i < length; ++i)
s->myarray = 2*i;
return s;
}
in main.c
#include "test.h"
#include <stdio.h>
int main()
{
int len = 10;
struct mystruct *c = new_mystruct(len);
myprint(c, len);
printf("%f", c->myarray[3]); // error: dereferencing pointer to incomplete type
return 0;
myprint() prints out 0 2 4 6 8 10 12 14 16 18. why doesn't the myprint(function work but the printf statement doesn't? why is it ok to pass it into a function but not use it in main? Thanks.
Currently main() only knows that struct mystruct is a type, but it doesn't know anything about its internal structure, because you've hidden it in test.c.
So you need to move this definition:
struct mystruct {
int *myarray;
};
from test.c to test.h, so that it's visible to main().
Note: what you're doing here is a classic example of an opaque type. This can be a very useful technique when you want to hide implementation details from code that is going to be calling your API.
Main.c doesn't know the contents of the mystruct structure. Try moving these lines:
struct mystruct {
int *myarray;
};
from test.c to test.h.
While you're at it, I think you mean "int myarray" not "int *myarray".
I am trying to create a function which allocates memory for a structure array defined in "main". The problem seems to be that my function does not recognize the structure. What is wrong with the following code?
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct typecomplex { float r; float i; } complex;
complex *myfunction(int n);
int main (int argc, char *argv[]) {
complex *result = myfunction(1000);
exit(0);
}
... and in another file...
struct complex *myfunction(int n) {
complex *result = (complex *)malloc(n*sizeof(*complex));
if(result==NULL) return(NULL);
else return(result);
}
Building on fvdalcin's answer:
myprog.c:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "mycomplex.h"
int main (int argc, char *argv[]) {
complex *result = myfunction(1000);
exit(0);
}
mycomplex.h:
#ifndef __MYCOMPLEX_H__
typedef struct typecomplex { float r; float i; } complex;
complex *myfunction(int n);
#define __MYCOMPLEX_H__
#endif
(The #ifdef's are a good idea to keep it from being included more than once.)
mycomplex.c:
#include <stdlib.h>
#include "mycomplex.h"
complex *myfunction(int n) {
complex *result = malloc(n*sizeof(complex));
if(result==NULL) return(NULL);
else return(result);
}
Note subtle but important fixes here--sizeof(complex) instead of sizeof(complex*), declaration of myfunction() doesn't include the keyword "struct", and no cast on malloc()--it doesn't need one and can hide the fact that you may be missing the include file with its prototype (see Do I cast the result of malloc?). myfunction() could actually by simplified down to one line:
return malloc(n*sizeof(complex));
Move this declaration typedef struct _complex { float r; float i; } complex; to the "other" file. This other file has to be your foo.h file, which has an foo.c equivalent which implements the methods declared in the foo.h. Then you can simply add the foo.h to your main.c file and everything will work fine.
Here is a code with corrections that compiles well:
typedef struct typecomplex { float r; float i; } complex;
complex *myfunction(int n) {
complex *result = (complex *)malloc(n*sizeof(complex)); //removed * from sizeof(*complex)
if(result==NULL) return(NULL);
else return(result);
}
int main (int argc, char *argv[]) {
complex *result = myfunction(1000);
exit(0);
}