Sscanf question
#1

Hi,

I'm my gamemode (PPC Trucking V2), I have this enum and array:
pawn Код:
// Setup a custom type that holds all data about a route
enum TRoute
{
    RouteName[128], // Holds the name of the route
    Cargo, // This holds the ID of the cargo to transport on these routes
    LineNumber, // This holds the line-number for this route
    PCV_Required, // This holds the vehicle-type and playerclass combo the player needs to use this route
    Homebase, // Holds the LocationID for this route's homebase
    SrcLocs[45], // This array holds all loading-points for this route
    DestLocs[45] // This array holds all unloading-points for this route
}
// Setup an array that holds all route-data
new ARoutes[MAX_ROUTES][TRoute];
As I'll be converting my files into MySQL tables later on, I want all this data stored into MySQL.
The problem is the SrcLocs and DestLocs fields.
These fields hold the Location_ID's (which refer to the ALocations array's indices) for the route.
Any Source-Location can be used to pickup the Cargo and any Destination-Location is a drop-off point for that cargo.

Right now, the file holds all SrcLocs and DestLocs below eachother, like this:
pawn Код:
[Route]
PCVRequired TruckerOreTrailer
RouteName Wheat transport
CargoID 10
SourceLocationID 21
SourceLocationID 22
DestinationLocationID 18
DestinationLocationID 23
DestinationLocationID 24
[/Route]

[Route]
PCVRequired TruckerFluidsTrailer
RouteName Unleaded fuel transport
CargoID 11
SourceLocationID 8
SourceLocationID 25
SourceLocationID 26
DestinationLocationID 27
DestinationLocationID 28
DestinationLocationID 29
DestinationLocationID 30
DestinationLocationID 31
DestinationLocationID 32
DestinationLocationID 33
DestinationLocationID 34
[/Route]

[Route]
PCVRequired TruckerFluidsTrailer
RouteName Chemicals transport
CargoID 16
SourceLocationID 37
DestinationLocationID 6
DestinationLocationID 15
DestinationLocationID 39
DestinationLocationID 40
[/Route]

[Route]
PCVRequired TruckerCargoTrailer
RouteName Bridge parts transport
CargoID 54
SourceLocationID 216
DestinationLocationID 177
DestinationLocationID 178
DestinationLocationID 179
DestinationLocationID 180
DestinationLocationID 181
DestinationLocationID 182
DestinationLocationID 183
DestinationLocationID 184
DestinationLocationID 185
DestinationLocationID 186
DestinationLocationID 187
DestinationLocationID 188
DestinationLocationID 189
DestinationLocationID 190
DestinationLocationID 191
DestinationLocationID 192
DestinationLocationID 193
DestinationLocationID 194
DestinationLocationID 195
DestinationLocationID 196
DestinationLocationID 197
DestinationLocationID 198
DestinationLocationID 199
DestinationLocationID 200
DestinationLocationID 201
DestinationLocationID 202
DestinationLocationID 203
DestinationLocationID 204
DestinationLocationID 205
DestinationLocationID 206
DestinationLocationID 207
DestinationLocationID 208
DestinationLocationID 209
DestinationLocationID 210
DestinationLocationID 211
DestinationLocationID 212
DestinationLocationID 213
DestinationLocationID 214
DestinationLocationID 215
[/Route]
You can see almost no route has 45 Source-Locations and 45 Destination-Locations.
In the file, unused locations aren't saved to keep the file a small as possible.



For MySQL:
Since both fields can have up to 45 locations, this would require at least 90 columns in MySQL (of which most would be empty (default value 0, as Location-ID 0 won't be used).
Storing all this data in the enum requires 95 columns.

But I was thinking to just have one column for the SrcLocs and one column for the DestLocs.
Every Location-ID would be stored as text with a space between them.
pawn Код:
Source-locations:
"7 44 47 48"

Destination-locations:
"49 50 51 52 53"
Instead of in the file:
pawn Код:
[Route]
PCVRequired TruckerNoTrailer
RouteName Food transport
CargoID 23
SourceLocationID 7
SourceLocationID 44
SourceLocationID 47
SourceLocationID 48
DestinationLocationID 49
DestinationLocationID 50
DestinationLocationID 51
DestinationLocationID 52
DestinationLocationID 53
[/Route]
This way I could cut down severely on the amount of columns as 45 columns would be merged into 1.

I thought about saving it as a string (just dump the SrcLocs and DestLocs enum fields as string), but I guess each index of those fields would be converted to 8-bit values and my entire data would be messed up as Location-ID's can be higher than 255.

Is there a way for sscanf to extract ALL values from that huge string as optional variables?
Or a direct way to populate the SrcLocs array with all indices filled for the data that's presented?

For the string "49 50 51 52 53", sscanf should be able to put all given values like this:
pawn Код:
ARoutes[RouteID][DestLocs][0] = 49;
ARoutes[RouteID][DestLocs][1] = 50;
ARoutes[RouteID][DestLocs][2] = 51;
ARoutes[RouteID][DestLocs][3] = 52;
ARoutes[RouteID][DestLocs][4] = 53;
While all other indices remain at 0, because there is no more data in the string to populate the rest.

Is this possible somehow?
Without doing something like this:
pawn Код:
sscanf(HugeString, "I(0)I(0)I(0)I(0)I(0)I(0)I(0)I(0)I(0)I(0)....", ARoutes[RouteID][SrcLocs][0], ARoutes[RouteID][SrcLocs][1], ARoutes[RouteID][SrcLocs][2], ARoutes[RouteID][SrcLocs][3], ARoutes[RouteID][SrcLocs][4], ARoutes[RouteID][SrcLocs][5], ARoutes[RouteID][SrcLocs][6], ARoutes[RouteID][SrcLocs][7], ARoutes[RouteID][SrcLocs][8], ARoutes[RouteID][SrcLocs][9], ....);
But then up to 45 times the "I(0)" and further parameters.
This line would become VERY long if this would be the only way.

PS: sorry for my long post.



EDIT: just noticed the array-option in the sscanf topic:
pawn Код:
new
    arr[5];
sscanf("1 2 3 4 5", "a<i>[5]", arr);
But enum string fields aren't exactly arrays I guess.
Would it work for my SrcLocs and DestLocs as well?
And how does this work when there are less values presented than required?
Reply
#2

Storing those values as string (data type) in the table is the best option.

For example, loop through them (SrcLocs) and save it as: "value0,value1,value2,value3...value44" (supposed to be numbers). Afrer loading the field:
pawn Код:
new p[45];
sscanf(DataFromFieldhere, "p<,>a<i>[45]", p);
they're assigned to p array. All you have to do is copy them to ARoutes array and to the correct route id of it.
Reply
#3

Just made a quick test:
pawn Код:
// Setup a custom type that holds all data about a route
enum TRoute
{
    RouteName[128], // Holds the name of the route
    Cargo, // This holds the ID of the cargo to transport on these routes
    LineNumber, // This holds the line-number for this route
    PCV_Required, // This holds the vehicle-type and playerclass combo the player needs to use this route
    Homebase, // Holds the LocationID for this route's homebase
    SrcLocs[45], // This array holds all loading-points for this route
    DestLocs[45] // This array holds all unloading-points for this route
}
// Setup an array that holds all route-data
new ARoutes[3][TRoute];


// Under OnFilterscriptInit:
    sscanf("49,50,51,52,53", "p<,>a<i>[45]", ARoutes[1][SrcLocs]);
    for (new i; i < 45; i++)
        printf("Index %i = %i, %i, %i", i, ARoutes[0][SrcLocs][i], ARoutes[1][SrcLocs][i], ARoutes[2][SrcLocs][i]);
It printed the correct data:

Код:
[16:59:55] Index 0 = 0, 49, 0
[16:59:55] Index 1 = 0, 50, 0
[16:59:55] Index 2 = 0, 51, 0
[16:59:55] Index 3 = 0, 52, 0
[16:59:55] Index 4 = 0, 53, 0
[16:59:55] Index 5 = 0, 0, 0
[16:59:55] Index 6 = 0, 0, 0
[16:59:55] Index 7 = 0, 0, 0
[16:59:55] Index 8 = 0, 0, 0
[16:59:55] Index 9 = 0, 0, 0
[16:59:55] Index 10 = 0, 0, 0
[16:59:55] Index 11 = 0, 0, 0
[16:59:55] Index 12 = 0, 0, 0
[16:59:55] Index 13 = 0, 0, 0
[16:59:55] Index 14 = 0, 0, 0
[16:59:55] Index 15 = 0, 0, 0
[16:59:55] Index 16 = 0, 0, 0
[16:59:55] Index 17 = 0, 0, 0
[16:59:55] Index 18 = 0, 0, 0
[16:59:55] Index 19 = 0, 0, 0
[16:59:55] Index 20 = 0, 0, 0
[16:59:55] Index 21 = 0, 0, 0
[16:59:55] Index 22 = 0, 0, 0
[16:59:55] Index 23 = 0, 0, 0
[16:59:55] Index 24 = 0, 0, 0
[16:59:55] Index 25 = 0, 0, 0
[16:59:55] Index 26 = 0, 0, 0
[16:59:55] Index 27 = 0, 0, 0
[16:59:55] Index 28 = 0, 0, 0
[16:59:55] Index 29 = 0, 0, 0
[16:59:55] Index 30 = 0, 0, 0
[16:59:55] Index 31 = 0, 0, 0
[16:59:55] Index 32 = 0, 0, 0
[16:59:55] Index 33 = 0, 0, 0
[16:59:55] Index 34 = 0, 0, 0
[16:59:55] Index 35 = 0, 0, 0
[16:59:55] Index 36 = 0, 0, 0
[16:59:55] Index 37 = 0, 0, 0
[16:59:55] Index 38 = 0, 0, 0
[16:59:55] Index 39 = 0, 0, 0
[16:59:55] Index 40 = 0, 0, 0
[16:59:55] Index 41 = 0, 0, 0
[16:59:55] Index 42 = 0, 0, 0
[16:59:55] Index 43 = 0, 0, 0
[16:59:55] Index 44 = 0, 0, 0
So it's safe to say it works not only with global arrays (or local when declared in a function), but also with enum string-fields.
So I can also skip creating an array first and copying the data afterwards.

Ty very much.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)