简体   繁体   中英

fscanf format specifier into structs

I have a data format like the following:

22/March/2014
137 8
15 16 34 8 18
17/November/2014
106 8
22 29 30 9 6
20/November/2014
169 10
50 58 38 29 1

I am trying to use fscanf to get the contents of the file and place them into the following struct:

    struct date{

    //This is storing the date dd/month/yyyy.
    char* fullDate;

    // Number of foot and wheelchair passengers.
    int foot;
    int wheelchair;

    //number of infant, child, adult, senior and family tickets sold
    int infant;
    int child;
    int adult;
    int senior;
    int family;
};

So i tried the following:

struct date r[50];
    FILE* der = fopen("C:\\Users\\Def\\Downloads\\annual_sales_data_2014.txt","r");
    int i = 0;
    rewind(der);
    fscanf(der, "%s", r[i].fullDate);
    fscanf(der, "%d %d ", &r[i].foot, &r[i].wheelchair);
    fscanf(der, "%d %d %d %d",&r[i].infant, &r[i].child, &r[i].adult, &r[i].senior, &r[i].family);
    printf("%s\n%d %d\n%d %d %d %d %d\n\n", r[i].fullDate, r[i].foot, r[i].wheelchair, r[i].infant, r[i].child, r[i].adult, r[i].senior, r[i].family);

    fclose(der);

But i believe that fscanf is not being used right and i'm getting a bit confused by the documentation for format specifiers, I have also tried it this way.

    fscanf(der, "%s/%s/%s\n%d %d\n%d %d %d %d %d\n", r[i].day, r[i].month, , r[i].year, &r[i].foot, &r[i].wheelchair, &r[i].infant, &r[i].child, &r[i].adult, &r[i].senior, &r[i].family);

In the above example i also catered the struct to accept 3 char*'s for the day month and year. in the beginning of the format specifiers string. This didn't work either so i broke it down to a smaller format to see if i could diagnose the problem.

Even in the broken down example this

fscanf(der, "%s", r[i].fullDate);

even this breaks in the debugger and cant work out why.

Thanks.

fullDate must be initialized before using. The simplest way is:

r[i].fullDate = malloc(whatever_size_you_need);

or you may even declare it as an array to avoid extra initialization:

struct date{

    //This is storing the date dd/month/yyyy.
    char fullDate[proper_size];

    // ...
};

Of course you must ensure somehow that read string will fit into buffer.

You cannot parse the date with fscanf(der, "%s", r[i].fullDate); because fulldate is an uninitialized pointer. You are supposed to pass the address of an array for the %s format. Put an array in the structure instead of a pointer, such as char fullDate[30]; and use fscanf(der, "%29s", r[i].fullDate);

Note that you can parse the date components directly with:

char monthName[16];
int day, year;

if (fscanf("%d/%15[^ /]/%d", &day, monthName, &year) == 3) {
    /* Date parsed correctly */
} else {
    /* At least one field missing, bail out */
    exit(1);
}

You say you believe that fscanf is not being used right, and that is true. This line

fscanf(der, "%d %d %d %d", &r[i].infant, &r[i].child, &r[i].adult, &r[i].senior, &r[i].family);

is passing arguments for the 5 fields you want to fill, but it only has 4 format format specifiers. Try this:

fscanf(der, "%d %d %d %d %d", &r[i].infant, &r[i].child, &r[i].adult, &r[i].senior, &r[i].family);

In addition, you should always check the data fields were read properly. The return value from fscanf would have told you that only 4 items were read.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM