# Thread: Structures problem

1. ## Structures problem

Writing a weather program and I'm using a structure to keep the current weather data. Right now I have two source files - main.c and rssparse.c. rssparse contains all the functions I need to read the data.

I have the "current" structure defined in main.c as...

Code:
```.....<insert includes and other stuff here>
struct weatherdata{
int temp;
char *status;
int humidity;
int windspeed;
char winddirection;
float barometer;
int dewpoint;
int heatindex;
int windchill;
int visibility;
} current;

int main(void){
<....program goes here>```
Then in rssparse.c I'm trying to access that in a function via -

Code:
```      if (!strcmp(idname, "humidity")) current.humidity = atoi(value);
else if (!strcmp(idname, "windspeed")) current.windspeed = atoi(value);
else if (!strcmp(idname, "dewpoint")) current.dewpoint = atoi(value);
else if (!strcmp(idname, "heatindex")) current.heatindex = atoi(value);
else if (!strcmp(idname, "windchill")) current.windchill = atoi(value);
else if (!strcmp(idname, "visibility")) current.visibility = atoi(value);```
Compile and...

In file included from main.c:30:
rssparse.c: In function `ParseHTML':
rssparse.c:160: error: `current' undeclared (first use in this function)
rssparse.c:160: error: (Each undeclared identifier is reported only once
rssparse.c:160: error: for each function it appears in.)
main.c: At top level:
main.c:50: error: `current' used prior to declaration
I've tried declaring the structure in rssparse in every way I can think of. extern struct current, extern current, etc. All I want to do is access the bloody structure globally!

So do any of you C gods know what I'm doing wrong?

2. in rssparse.c:
Code:
```extern struct weatherdata{
int temp;
char *status;
int humidity;
int windspeed;
char winddirection;
float barometer;
int dewpoint;
int heatindex;
int windchill;
int visibility;
} current;```

3. Done and:
main.c:39: error: redefinition of `struct weatherdata'
jlpence@linux:~/weather>
At least I'm down to one error.

4. Post main.c, at least any references to struct weatherdata

5. Originally posted by major_blagger
in rssparse.c:
Code:
```extern struct weatherdata{
int temp;
char *status;
int humidity;
int windspeed;
char winddirection;
float barometer;
int dewpoint;
int heatindex;
int windchill;
int visibility;
} current;```
No. This is wrong. It should just be:
Code:
`extern struct weatherdata current;`
Because otherwise, like the error says, you're redefining the whole structure. You just want an instance, not a redefinition. And actually, you'd be best served moving your structure definition to a header file instead. Then wrapping it nicely in some #ifndef #define #endif statments.

Quzah.

6. The top of the code for both programs:

main.c
Code:
```#define TRUE 1
#define FALSE 0
#define DEBUG 1      // Verbose output, handy for development
#define SUPERDEBUG 0 // VERY verbose output! Annoying but helpful.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "rssparse.c"

extern int ProcessRSSFeed(char *filename);
int FileExists(char *filename);
int GetFileSize(char *filename);
void DebugMsg (char *message, char *info);
void Fatal (char *message, char *info);
void SDebugMsg (char *message, char *info);

struct weatherdata{
int temp;
char *status;
int humidity;
int windspeed;
char winddirection;
float barometer;
int dewpoint;
int heatindex;
int windchill;
int visibility;
} current;

int main(void){
.....Code goes here```
rssparse.c
Code:
```static int ClosingTag(char *buffer, char *tag);
int ProcessRSSFeed(char *filename);
static void Cut (char *begin, char *end);
static void ParseBracketTag(char *buffer);
static void ParseHTML(char *buffer);
static void ParseXML(char *buffer);

extern int FileExists(char *filename);
extern int GetFileSize(char *filename);
extern void DebugMsg (char *message, char *info);
extern void Fatal (char *string, char *buffer);
extern void SDebugMsg (char *message, char *info);

extern struct weatherdata current;

static int ClosingTag(char *buffer, char *tag){
.....more code goes here```
Note that I did try quzah's advice (included in above code, in fact), and got the following:
rssparse.c: In function `ParseHTML':
rssparse.c:161: error: invalid use of undefined type `struct weatherdata'
rssparse.c:162: error: invalid use of undefined type `struct weatherdata'
rssparse.c:163: error: invalid use of undefined type `struct weatherdata'
rssparse.c:164: error: invalid use of undefined type `struct weatherdata'
rssparse.c:165: error: invalid use of undefined type `struct weatherdata'
rssparse.c:166: error: invalid use of undefined type `struct weatherdata'
jlpence@linux:~/weather>
Accessing the structures via the exact code listed in my first post.

7. You need to use a header file.

Code:
`#include "rssparse.c"`
It is not a good idea to include one c file in another. You need to create a header file.

Sample rssparse.h:
Code:
```/* Declare the structure so that every file can use it */
struct weatherdata{
int temp;
char *status;
int humidity;
int windspeed;
char winddirection;
float barometer;
int dewpoint;
int heatindex;
int windchill;
int visibility;
};

/* Declare an instance of the structure. It is labelled extern
* so that each file knows the instance exists but space is
* not reserved. */
extern struct weatherdata current;```
#include this header in every C file where you want to use the "weatherdata" structure or the instance "current".

Now, in one c file only, you have to declare the instance.
Code:
`struct weatherdata current`
This reserves space for "current". Each other file where "current" is used is told to link to this space by the extern declaration.

8. Originally posted by quzah
No. This is wrong. It should just be:
Code:
`extern struct weatherdata current;`
Because otherwise, like the error says, you're redefining the whole structure. You just want an instance, not a redefinition. And actually, you'd be best served moving your structure definition to a header file instead. Then wrapping it nicely in some #ifndef #define #endif statments.

Quzah.
What compiler do you use? This fails to compile with (my) MVS6 and LCC because the file has no idea what any of the fields in weatherdata are.

As far as I can see the redefinition error is because he is including rssparse.c before defining it in main.

main.c:
Code:
```#include <stdio.h>

struct weatherdata{
int temp;
char *status;
int humidity;
int windspeed;
char winddirection;
float barometer;
int dewpoint;
int heatindex;
int windchill;
int visibility;
} current;

void test();

int main(void)
{
current.temp = 3;
printf("%d\n", current.temp); /* prints 3 */
test();
printf("%d\n", current.temp); /* prints 4 */
return 0;
}```
test.c:
Code:
```/* extern not required as, being outside of a function
it is implied */
extern struct weatherdata{
int temp;
char *status;
int humidity;
int windspeed;
char winddirection;
float barometer;
int dewpoint;
int heatindex;
int windchill;
int visibility;
} current;

void test()
{
/* if struct weatherdata current was defined here
it was have to be extern otherwise the compiler
wouldn't know you were talking about another
struct weatherdata current */
current.temp = 4;
}```
compiles and runs fine for me. The only problem being if i made a mistake with the weatherdata structure, therefore it should be put in a header file, just as in the above post.

9. Dear anonytmouse,

After two days of mucking with this it finally works. I would like to buy you beer.

Love,
me.

10. Originally posted by major_blagger
As far as I can see the redefinition error is because he is including rssparse.c before defining it in main.
No. The redefinition was you telling him to define it again in rssparce.c. The structure definition should be in a header, and the variable instance should be as I originally stated.

Quzah.

11. Originally posted by quzah
No. The redefinition was you telling him to define it again in rssparce.c. The structure definition should be in a header, and the variable instance should be as I originally stated.

Quzah.
Ok.

Could you help explain why the code I posted compiles and runs fine with no warnings, but if I add the line #include "test.c" to main.c I get a redefinition error.

There is no difference to the compiler whether you add the structure at the start of the file, or include it in a header (unless you also #include the source..as was done here. This is where the #ifndef is important).

Each file still has to define what the variable is. extern just makes the name visible between files. It's no different than extern float var or extern double var. You're not doing any redefinition, you're just saying, the variable name I'm going to be playing around with is refering to the same variable in another file. You use header files to protect yourself from accidently changing the type but that is a stylistic point, rather than a language issue.

As an example (without header files) compiling main.c and test.c

main.c
Code:
```#include <stdio.h>

struct weatherdata{
int temp;
} current;

void test();

int main(void)
{
current.temp = 3;
printf("%d\n", current.temp); /* prints 3 */
test();
printf("%d\n", current.temp); /* should print 4 */
return 0;
}```
test.c
Code:
```extern struct weatherdata current;
void test()
{
current.temp =  4;
}```
This will not and should not compile.

new test.c
Code:
```extern struct weatherdata{
int temp;
} current;

void test()
{
current.temp =  4;
}```
Will compile and work correctly. In fact, the structure need not even be called weatherdata. The variable MUST be called current though to be correctly (externally) linked.

Where am I going wrong here?

Popular pages Recent additions