Thread: Structures problem

  1. #1
    Registered User
    Join Date
    Jan 2004
    Posts
    26

    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. #2
    Registered User
    Join Date
    Feb 2004
    Posts
    72
    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. #3
    Registered User
    Join Date
    Jan 2004
    Posts
    26
    Done and:
    main.c:39: error: redefinition of `struct weatherdata'
    jlpence@linux:~/weather>
    At least I'm down to one error.

  4. #4
    Registered User
    Join Date
    Feb 2004
    Posts
    72
    Post main.c, at least any references to struct weatherdata

  5. #5
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    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.
    Hope is the first step on the road to disappointment.

  6. #6
    Registered User
    Join Date
    Jan 2004
    Posts
    26
    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. #7
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    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. #8
    Registered User
    Join Date
    Feb 2004
    Posts
    72
    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.
    Last edited by major_blagger; 03-13-2004 at 02:07 PM.

  9. #9
    Registered User
    Join Date
    Jan 2004
    Posts
    26
    Dear anonytmouse,

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

    Love,
    me.


  10. #10
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    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.
    Hope is the first step on the road to disappointment.

  11. #11
    Registered User
    Join Date
    Feb 2004
    Posts
    72
    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?
    Last edited by major_blagger; 03-13-2004 at 06:20 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 26
    Last Post: 06-11-2009, 11:27 AM
  2. searching problem
    By DaMenge in forum C Programming
    Replies: 9
    Last Post: 09-12-2005, 01:04 AM
  3. Bin packing problem....
    By 81N4RY_DR460N in forum C++ Programming
    Replies: 0
    Last Post: 08-01-2005, 05:20 AM
  4. Words and lines count problem
    By emo in forum C Programming
    Replies: 1
    Last Post: 07-12-2005, 03:36 PM
  5. half ADT (nested struct) problem...
    By CyC|OpS in forum C Programming
    Replies: 1
    Last Post: 10-26-2002, 08:37 AM