Problem with splitting a mysql string with sscanf 2.6
#1

Hello

I want to load vehicles from a MySQL table. For this I use BlueG MySQL plugin rev. 5 and sscanf 2.6 on Linux. The string from the mysql table is correct, but the splitting goes wrong (In my opinion).

Enum for the vehicle(row):
Code:
enum vehicleinfo
{
    ID,
    Status,
    Plate[10],
    Model,
    FractionID,
    JobID,
    Noob,
    Locked,
    Towed,
    Tunable,
    Float:X1,
    Float:Y1,
    Float:Z1,
    Float:A1,
    Float:X2,
    Float:Y2,
    Float:Z2,
    Float:A2,
    Owner[30],
    Key1[30],
    Key2[30],
    Color1,
    Color2,
    Paintjob,
    T0,
    T1,
    T2,
    T3,
    T4,
    T5,
    T6,
    T7,
    T8,
    T9,
    T10,
    T11,
    T12,
    T13
};
Code for loading a vehicle
Code:
LoadVehicles()
{
    new query[512], string[512];
    for(new i = 1; i < MAX_VEHICLES; i++)
    {
        format(query,512, "SELECT * FROM Vehicle WHERE ID = '%d'", i);
        mysql_query(query);
        mysql_store_result();
        if(mysql_num_rows() > 0)
        {
            mysql_fetch_row(string);
            mysql_free_result();
            printf("%s", string);
            sscanf(string, "e<p<|>dds[10]dddddddffffffffs[30]s[30]s[30]ddddddddddddddddd>", Vehicle[i]);
            if(Vehicle[i][Status])
            {
                new vehicleid = -1;
                new respawntime = -1;
                if(Vehicle[i][Noob])
                {
                    respawntime = 600000;
                }
                if(!Vehicle[i][Towed])
                {
                    printf("Model: %d FractionID: %d JobID: %d Noob: %d Locked: %d Towed: %d Tunable: %d", Vehicle[i][Model], Vehicle[i][FractionID], Vehicle[i][JobID], Vehicle[i][Noob], Vehicle[i][Locked], Vehicle[i][Towed], Vehicle[i][Tunable]);
                    printf("X1: %f Y1: %f Z1: %f A1: %f ", Vehicle[i][X1], Vehicle[i][Y1], Vehicle[i][Z1] + 1, Vehicle[i][A1]);
                    vehicleid = CreateVehicle(Vehicle[i][Model], Vehicle[i][X1], Vehicle[i][Y1], Vehicle[i][Z1] + 1, Vehicle[i][A1], Vehicle[i][Color1], Vehicle[i][Color2], respawntime);
                    printf("%d", vehicleid);
                }
                else
                {
                    printf("Towed");
                    vehicleid = CreateVehicle(Vehicle[i][Model], Vehicle[i][X2], Vehicle[i][Y2], Vehicle[i][Z1] + 1, Vehicle[i][A2], Vehicle[i][Color1], Vehicle[i][Color2], respawntime);
                }
                SetVehicleNumberPlate(vehicleid, Vehicle[i][Plate]);
                VehicleID[vehicleid] = Vehicle[i][ID];
                SetVehicleConfiguration(vehicleid);
            }
        }
    }
}
And the output from the server console. Pay attention for the NaN value (The second float should be the first, the third the second and the fourth the third (and then we don't have a third, because the first is NaN):

Code:
Wrong output: "Nan (At position X1 we have an invalid value)", "1126.530029 (X1, but at position of Y1)", "-1451.319946 (Y1,  but at position of Z1)", "15.516900 (Z1,  but at position of A1")
As you can see, the output should be:

Code:
"1126.53 (X1)", "-1452.32 (Y1)", "15.5169 (Z1)", "351.84 "A1"
The output fromt he server console:

Code:
[23:36:23] 1|1|Terra|596|44|55|66|77|0|99|1126.53|-1452.32|15.5169|351.84|0|0|0|0|Keiner|Keiner|Keiner|0|1|-1|0|0|0|0|0|0|0|0|0|0|0|0|0|0
[23:36:23] Model: 596 FractionID: 44 JobID: 55 Noob: 66 Locked: 77 Towed: 0 Tunable: 99
[23:36:23] X1: NaN Y1: 1126.530029 Z1: -1451.319946 A1: 15.516900 
[23:36:23] 1
And I attached a screen from the mysql table in PHPMyAdmin


I don't what happens, is this really a bug in sscanf or did I a very stupid mistake ?

Dudalus
Reply
#2

Well, you are saving values greater than 1 in a tinyint field. Not exactly sure if that would affect the result. Sscanf statement looks fine as far as I can see.

But honestly, tell me who taught you to load stuff like this;
pawn Code:
for(new i = 1; i < MAX_VEHICLES; i++)
    {
        format(query,512, "SELECT * FROM Vehicle WHERE ID = '%d'", i);
That's seriously inefficient and ruins the whole point of MySQL.
Reply
#3

Hello

Yes, you are rigth. That was only for testing, because I cut a part above the for loop (But this part doesn't caused the problem). I changed the size of the integers to 11, but I have still the same problem.

Edit:

This code works, but I won't use it because for this I use sscanf:
Code:
            sscanf(string, "p<|>dds[10]dddddddffffffffs[24]s[24]s[24]ddddddddddddddddd", Vehicle[i][ID], Vehicle[i][Status], Vehicle[i][Plate], Vehicle[i][Model], Vehicle[i][FractionID],
            Vehicle[i][JobID], Vehicle[i][Noob], Vehicle[i][Locked], Vehicle[i][Towed], Vehicle[i][Tunable], Vehicle[i][X1], Vehicle[i][Y1], Vehicle[i][Z1], Vehicle[i][A1], Vehicle[i][X2], Vehicle[i][Y2],
            Vehicle[i][Z2], Vehicle[i][A2], Vehicle[i][Owner], Vehicle[i][Key1], Vehicle[i][Key2], Vehicle[i][Color1], Vehicle[i][Color2], Vehicle[i][Paintjob], Vehicle[i][T0], Vehicle[i][T1], Vehicle[i][T2],
            Vehicle[i][T3], Vehicle[i][T4], Vehicle[i][T5], Vehicle[i][T6], Vehicle[i][T7], Vehicle[i][T8], Vehicle[i][T9], Vehicle[i][T10], Vehicle[i][T11], Vehicle[i][T12], Vehicle[i][T13]);
Reply
#4

pawn Code:
sscanf(string, "e<p<|>dds[10]dddddddffffffffs[30]s[30]s[30]ddddddddddddddddd>", Vehicle[i]);
See the end of the line. You're using the vehicles ids, when instead you should be using the enumerator.
Reply
#5

But Vehicle is an enum for MAX_VEHICLES:

Code:
new Vehicle[MAX_VEHICLES][vehicleinfo];
Reply
#6

You don't have to mention the enumerator itself in the scipt. Interesting... There's a little mistake in using one function. You have to use mysql_free_result at the end, not at the beginning of the script. I did a little searching and lets see if that makes some difference:

pawn Code:
sscanf(string, "p<|>e<dds[10]dddddddffffffffs[30]s[30]s[30]ddddddddddddddddd>", Vehicle[i]);
Reply
#7

Hello

The problem still exists. In the sscanf topic, there is an entry about delemiter. In this case, your version is invalid ?

https://sampforum.blast.hk/showthread.php?tid=120356

Quote:

The old version will still work, but it will give a warning. Enum specifications can include delimiters, and is the only time "<>"s are contained in other "<>"s:

pawn Code:

sscanf("1 12.0 Bob,c", "e<ifp<,>s[32]c>", var);


Note that the delimiter will remain in effect after the enum is complete.

Dudalus
Reply
#8

The problem might be in the small integers as Vince said. Look at the Locked and Tunable value sizes of mysql. It is 1 bit size. But then in the saved mysql file, you have 2 bit size - 77 and 99. I would suggest to make them bigger than 1 or 11 as the others.

EDIT: Damn it... Didn't see that you changed them. But why don't you use the working one script ? Well if it works with the other script, it means that the problem is in sscanf part.
Reply
#9

Sorry for the late replay. First these fields where booleans. I thought this would be the problem and changed the data type to int, but PHPMyAdmin didn't change the field size (I changed it/retested it, but same problem).

I will recheck it again and then post in the sscanf thread. I don't want use the working script, because for this reason I use sscanf (splitting into an array/enumeration)
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)