Search code examples
cstringdata-structuresscanfseparator

Scan a line with spaces and symbols to separate the entries and using structures in C


So the purpose of this code is to scanf a sentence like this one:

In my house#House#28#-134.943|47.293#21-24

The code must scan 6 different parts separated by '#'. The first one, "In my house" is the location of the party, the second one "House" is the type of place where there will be the party, the third one "28" is walk time to arrive there, the fourth one "-134.943|47.293" are the latitude and longitude (to find the place) separated by a '|', and finally, "21-24" is the time when the party starts and when it finishes. All of the previous parameters have to be saved in different variables that are into a structure like the following one:

typedef struct {
    
    char name[MAX];                     //name of the location
    char location_type[MAX];            //type of location
    int travel;                         //time to arrive
    int latitude;                   
    int longitude;                  
    int hours[5];                       //when the party starts and ends
    
} Locations;

And then, everything is stored neatly for every party location.

So, I'm asking for a function that asks and stores all that information (separated by "#" and "|") in the structure we have seen before. This function is something like this:

int AddLocation(Locations location[]) {
    
    int i = 0;
    
    i = num_locations;
    
    printf ("Location information: ");
    
    // here should be the scanf and this stuff
        
    i++;
    
    return i;
}

Solution

  • Making a few changes to the format (namely, lat/long need to be floats, and I'm not sure what you meant to do with the int array for hours), you could do something like:

    #include <stdio.h>
    
    #define MAX 32
    
    struct loc {
            char name[MAX];
            char location_type[MAX];
            int travel;
            float latitude;
            float longitude;
            char hours[MAX];
    };
    
    int
    main(void)
    {
            struct loc Locations[16];
            struct loc *t = Locations;
            struct loc *e = Locations + sizeof Locations / sizeof *Locations;
            char nl;
            char fmt[128];
    
            /* Construct fmt string like: %31[^#]#%31[^#]#%d#%f|%f#%31[^\n]%c */
            snprintf(fmt, sizeof fmt,
                    "%%%1$d[^#]#%%%1$d[^#]#%%d#%%f|%%f#%%%1$d[^\n]%%c", MAX - 1);
            while( t < e
                    && 7 == scanf(fmt,
                            t->name, t->location_type, &t->travel,
                            &t->latitude, &t->longitude, t->hours, &nl
                    ) && nl == '\n'
            ) {
                    t += 1;
            }
            for( e = Locations; e < t; e++ ){
                    ; /* Do something with a location */
            }
    }