fscanf() filter

2019-09-16 14:34发布

问题:

I have a file with data in this format:

Name WeekDay Month day, Year StartHour:StartMin Distance Hour:Min:Sec

Example: John Mon September 5, 2011 09:18 5830 0:26:37

I want to scan this into a struct:

typedef struct {
    char name[20];
    char week_day[3];
    char month[10];
    int day;
    int year;
    int startHour; 
    int startMin;
    int distance;
    int hour;
    int min;
    int sec;
} List;

i use fscanf():

List listarray[100];
for(int i = 0; ch = fgetc(file) != 'EOF'; ch = fgetc(file), i++){
    if(ch != '\0'){
        fscanf(file, "%s %s %s %d %d %d %d %d %d %d %d", &listarray[i].name...etc)
    }
}

My issue is that I want to filter out the noise in the input string, that being:

Month day*,* year <- the comma is consistent in all entries. I just want the month in the char array, the day in int.

And the time stamps:

startHour:startmin and hour:min:sec <- here I want to filter out the colon.

Do I need to put it into a string first and then do some splitting, or can I handle it in fscanf?

Update:

Okay, så I've been trying to get this to work now, but I simply cannot. I literally have no idea what the issue is.

#include <stdio.h>

/*
 Struct to hold data for each runners entry
 */
typedef struct {

    char name[21];
    char week_day[4];
    char month[11];
    int date,
    year,
    start_hour,
    start_min,
    distance,
    end_hour,
    end_min,
    end_sec;

} runnerData;

int main (int argc, const char * argv[])
{
    FILE *dataFile = fopen("/Users/dennisnielsen/Documents/Development/C/Afleveringer/Eksamen/Eksamen/runs.txt", "r");
    char ch;
    int i, lines = 0;

    //Load file
    if(!dataFile)
        printf("\nError: Could not open file!");

    //Load data into struct.
    ch = getc(dataFile);

    //Find the total ammount of lines
    //To find size of struct array
    while(ch != EOF){
        if(ch == '\n')
            lines++;

        ch = getc(dataFile);
    }

    //Allocate memory
    runnerData *list = malloc(sizeof(runnerData) * lines);

    //Load data into struct
    for(i = 0; i < lines; i++){

        fscanf(dataFile, "%s %s %s %d, %d %d:%d %d %d:%d:%d %[\n]",
               list[i].name,
               list[i].week_day,
               list[i].month,
               list[i].date,
               list[i].year,
               list[i].start_hour,
               list[i].start_min,
               list[i].distance,
               list[i].end_hour,
               list[i].end_min,
               list[i].end_sec);

        printf("\n#%d:%s", i, list[i].name);
    }  

    fclose(dataFile);


    return 0;
}

I've been told that "only strings to do not require & in front of them in fscanf();" but I tried both with and without ampersand to no avail.

回答1:

Put the "noise" in the format string.

Also you might like to limit the size of strings.

And get rid of the & for arrays.

And test the return value from scanf!

// John Mon September 5, 2011 09:18 5830 0:26:37
if (scanf("%19s%2s%9s%d,%d%d:%d%d%d:%d:%d", ...) != 11) /* error */;
//             ^^^ error: not enough space

Notice week_day has space for 2 characters and the zero terminator only.



回答2:

You can put this noise in the scanf format string.

Note also that for date/time strings, you can use strptime. It does the same kind of job that scanf, but is specialized on date/times. You will bo able to use %Y, %M ... and other with it.



标签: c scanf