Thread: Sscanf into struct

  1. #1
    Registered User
    Join Date
    Nov 2020
    Posts
    6

    Sscanf into struct

    Hi all,

    I have a very frustrating issue trying to read formatted input from a file into a struct. I have defined two structs. Main calls the functions to load both. The ctrl struct loads perfectly and the code enters the next function, but even though I use the exact same method to load the soil struct, the code runs but all output stops just before the first sscanf call.

    Any help spotting the issue would be much appreciated - I've been looking at it for hours now.

    My structs are defined as follows:

    Code:
    <header file>
    
    #define MAXLYR              25
    
    typedef struct ctrl_struct
    {
        int             All;            // Run all counties Y/N?
        char            County[100];    // County Name if not all
        int             StartYear;      // Sim start year
        int             EndYear;        // Sim end year
    // some more parameters here, no arrays though
    
    } ctrl_struct;
    
    typedef struct soil_struct
    {
        double          CurveNumber;            /* curve number (-) */
        double          N;                              /* N layers */
        double          NodeDepth[MAXLYR];
        double          LayerDepth[MAXLYR];
    // more arrays ...
    
    } soil_struct;
    
    ---------------------------------------------
    
    <include header>
    
    int main(int argc, char *argv[])
    {
    
        ctrl_struct    *ctrl;
        soil_struct    *soil;
    
        ReadControlFile(ctrl);
    
        ReadSoilFile(ctrl, soil);
    
    } // end main
    
    void ReadControlFile(ctrl_struct *ctrl)
    {
    
    // Opens file fine
    //Read info (NextLine function is just in case of UTF-8 BOM, it just copies the line into cmdstr)
    
        NextLine(ControlFile, cmdstr, &lno);
        sscanf(cmdstr, "%*s %d", &ctrl->All);
    
        NextLine(ControlFile, cmdstr, &lno);
        sscanf(cmdstr, "%*s %s", &ctrl->County);
    
    // same method loads in the rest of the ctrl parameters fine
    
        printf("Finished loading control file \n");
        fclose(ControlFile);
    }
    
    void ReadSoilFile(ctrl_struct *ctrl, soil_struct *soil)
    {
    
    // opens file fine using info from ctrl struct
    
        NextLine(SoilFile, cmdstr, &lno);
        printf("%s\n", cmdstr);
    
    // CMDSTR PRINTS AS EXPECTED  (CURVE_NUMBER     78)
    // NO MORE OUTPUT
    
        sscanf(cmdstr, "%*s %lf", &soil->CurveNumber);
        printf("%lf\n", soil->CurveNumber);
    
        NextLine(SoilFile, cmdstr, &lno);
        sscanf(cmdstr, "%*s %lf", &soil->N);
    
        soil->NodeDepth[0] = 0;
        soil->NodeDepth[1] = 0.01;
        soil->NodeDepth[2] = 0.02;
        soil->NodeDepth[3] = 0.04;
        soil->NodeDepth[4] = 0.08;
        soil->NodeDepth[5] = 0.12;
        soil->NodeDepth[6] = 0.2;
        for(i = 7; i <= 25; i++){
            soil->NodeDepth[i] = soil->NodeDepth[i - 1] + 0.1;
        }
    
        double Depth, Sand, Clay, OM;
    
        NextLine(SoilFile, cmdstr, &lno);
        NextLine(SoilFile, cmdstr, &lno);
        sscanf(cmdstr, "%lf %*s %lf %lf %lf", &Depth, &Clay, &Sand, &OM);
    
    // fills up rest of arrays within soil struct based on values above
    
        printf("Finished loading soil file \n");
        fclose(SoilFile);
    
    }
    If I simply declare CurveNumber or N as a double outside of a struct, they load fine, and the variables I read in later (Depth/Clay/Sand) also read in fine, suggesting it's just the struct that's the issue. It's not because there are arrays in this struct though - they don't load even if I remove all the arrays from the soil struct.

    Also, if I get rid of the sscanf mess and just try to assign values to the array within the struct (as with NodeDepth above), that doesn't work. It works if I assign values to an array that is not in a struct, so again, it seems like the struct is the problem.

    Help!! Thank you!

  2. #2
    Registered User
    Join Date
    Dec 2017
    Posts
    1,107
    In main you need to define actual structs, not just pointers to structs.
    Then pass pointers by using the "address-of" operator, &.
    Code:
    int main() // Don't define argc and argv if you aren't using them.
    {
        ctrl_struct ctrl;
        soil_struct soil;
     
        ReadControlFile(&ctrl);
        ReadSoilFile(&ctrl, &soil);
        //...
     
        return 0;
    }
    The best argument against democracy is a five minute conversation with the average voter. - Churchill

  3. #3
    Registered User
    Join Date
    Nov 2020
    Posts
    6
    Quote Originally Posted by john.c View Post
    In main you need to define actual structs, not just pointers to structs.
    Then pass pointers by using the "address-of" operator, &.
    Code:
    int main() // Don't define argc and argv if you aren't using them.
    {
        ctrl_struct ctrl;
        soil_struct soil;
     
        ReadControlFile(&ctrl);
        ReadSoilFile(&ctrl, &soil);
        //...
     
        return 0;
    }
    Thank you so much! I looked back at where I had defined the ctrl struct and I hadn't used the * ... I knew this was going to be a facepalm moment, but at least now I know I need to brush up on pointers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. help with sscanf
    By khoavo123 in forum C Programming
    Replies: 2
    Last Post: 03-25-2012, 03:33 PM
  2. sscanf() help in c
    By ankitsinghal_89 in forum C Programming
    Replies: 2
    Last Post: 01-31-2009, 02:11 PM
  3. sscanf
    By cheryl_li in forum C Programming
    Replies: 2
    Last Post: 05-02-2003, 07:55 AM
  4. sscanf and gets
    By Max in forum C++ Programming
    Replies: 2
    Last Post: 10-21-2002, 07:09 AM
  5. SSCANF help
    By mattz in forum C Programming
    Replies: 7
    Last Post: 12-10-2001, 04:53 PM

Tags for this Thread