sscanf gibt falsche Werte zurück

In 10 Minuten startet der nächtliche Backupvorgang! Es kann währenddessen (ca. 10 Minuten) zu Einschränkungen bei der Nutzung des Forums kommen
Weitere Infos findet ihr im Thema Backup des Forums
Wichtiger Hinweis: Bitte ändert nicht manuell die Schriftfarbe auf schwarz sondern belasst es bei der Standardeinstellung. Somit tragt ihr dazu bei dass euer Text auch bei Verwendung unseren dunklen Forenstils noch lesbar ist!

Tipp: Ihr wollt längere Codeausschnitte oder Logfiles bereitstellen? Benutzt unseren eigenen PasteBin-Dienst Link
  • Hallo,


    mal wieder ein Problem, welches ich nicht lösen kann.


    Es geht um das sscanf2 Plugin von y_less.


    Ich hab folgenden Code verwendet:

    ocmd:showfinances(playerid, params[])
    {
    new pID,string[128];
    if(sscanf(params,"u",pID)) return SendClientMessage(playerid,COLOR_GREY,"Benutze /showfinances [Playerid]");
    printf("DEBUG: /showfinances %d", pID);
    .....
    return 1;
    }


    Debugausgabe:


    /showfinances test (Mein Name)
    Ausgabe: DEBUG: /showfinances 65535


    /showfinances 9 (Meine ID)
    Ausgabe: DEBUG: /showfinances 65535


    Das Problem besteht auch bei zwei weiteren Befehlen, in anderen Befehlen funktioniert es jedoch. Die Befehle sind zum teil mit dcmd und mit ocmd geschrieben.


    Vielleicht hat jemand eine Idee, was sscanf2 hier nicht gefällt.


    MfG
    Wepper


    Edit 1: Rechtschreibfehler behoben

    Mit freundlichem Gruß
    Weper

    Einmal editiert, zuletzt von wepper ()

  • Bist du dir sicher, das du die ID 9 bzw. den Namen richtig eingegeben hast?
    65535 ist der Wert, der zurückgegeben wird, wenn der Spieler nicht connected ist.


    EDIT:
    Bau mal diese Abfrage nach der sscanf-Abfrage ein:
    if(!IsPlayerConnected(pID))return SendClientMessage(playerid,-1,"Spieler existiert nicht!");

  • Hast du das neueste sscanf?
    Einfach mal updaten, evtl. hilft das


    Ja, laut Meldung im Log hab ich die aktuellste. Ich kann aber mal ein Update durchführen.


    Bist du dir sicher, das du die ID 9 bzw. den Namen richtig eingegeben hast?


    65535 ist der Wert, der zurückgegeben wird, wenn der Spieler nicht connected ist.


    Hallo. Der Spieler existiert. Ich hab den Namen mal in allen Versionen eingegeben (test,Test,t,TEST,...) und auch die richtige ID, aber es bleibt dabei, dass er die INVALID_PLAYER_ID returnt.

    Mit freundlichem Gruß
    Weper

  • Okay,


    Hab sscanf geupdatet, ohne erfolg.


    Hier mal ein Logauszug:

    Code
    [27/10/2014 14:34:24] test has logged in.
    [27/10/2014 14:34:37] DEBUG: /showfinances 65535 | playerid = 5 | params[] = test
    [27/10/2014 14:34:37] Spieler nicht verbunden
    [27/10/2014 14:34:51] DEBUG: /showfinances 65535 | playerid = 5 | params[] = t
    [27/10/2014 14:34:51] Spieler nicht verbunden
    [27/10/2014 14:34:53] DEBUG: /showfinances 65535 | playerid = 5 | params[] = 5
    [27/10/2014 14:34:53] Spieler nicht verbunden


    Und der Code mit der Ergänzung von @[NGD]Manne: sieht jetzt so aus:

    ocmd:showfinances(playerid, params[])
    {
    new pID,string[128];
    if(sscanf(params,"u",pID)) return SendClientMessage(playerid,COLOR_GREY,"Benutze /showfinances [Playerid]");
    printf("DEBUG: /showfinances %d | playerid = %d | params[] = %s", pID, playerid, params);
    if(!IsPlayerConnected(pID))return print("Spieler nicht verbunden");
    .......
    return 1;
    }

    Mit freundlichem Gruß
    Weper

  • Was ist wenn du das ganze mal komplett als integer umwandelst sprich,
    strval(pID);

    Das Problem ist halt, das sscanf mit pID schon mit nem falschen Wert füttert. Dieser Wert ist aber ein Integer (65535). Ich glaube eher, dass das Problem an sscanf liegt.


    Zum Problem:
    Ich hab gerade festgestellt, dass alle Befehle, die den User mit dem sscanf Parameter "u" ermitteln, nicht funktionieren. Muss ich irgendeineinen Speziellen Code einfügen für den Parameter?

    Mit freundlichem Gruß
    Weper

  • do.de - Domain-Offensive - Domains für alle und zu super Preisen
  • Wer benutzt denn bitte noch die Sscanf funktion?
    Es gibt schon so was feines wie sscanf2 mit Plugin.


    Ist das denn nicht sowas von egal?
    Der Stock spart auf jeden Fall Speicherplatz, welchen du irgendwann brauchen wirst.
    Wo ist denn eigentlich der Unterschied zwischen den beiden Varianten ;)?


    Und ja, ich bin noch so Oldschool und nutze den Stock :)

  • So. Mit dem "d" Parameter funktioniert die Geschichte, wer hätts gedacht ...
    Aber damit ist das Problem leider nicht behoben.


    Besteht die Möglichkeit, sscanf2 für die normalen sscanf Abfragen zu nutzen und den sscanf Stock für die Spielerabfragen?


    Oder hat jemand noch eine Idee zur Fehlerbehebung?


    PS:
    Nach Möglichkeit möchte ich die Plugin Version behalten, und nicht auf die stock Version umsteigen ...

    Mit freundlichem Gruß
    Weper

  • Warum willst du das machen? Entferne die stock Funktion von sscanf komplett aus deinem Code und inkludiere nur die sscanf2 Include.


    Alle Funktionen die das stock hat, hat auch das Plugin.
    Dann funktioniert auch das u.


    Ansonsten, wenn du wirklich beide Funktionen verwenden willst, benenne den stock um zu sscanfx, und nutze das für diese Abfragen.

  • Warum willst du das machen? Entferne die stock Funktion von sscanf komplett aus deinem Code und inkludiere nur die sscanf2 Include.


    Alle Funktionen die das stock hat, hat auch das Plugin.
    Dann funktioniert auch das u.


    Ansonsten, wenn du wirklich beide Funktionen verwenden willst, benenne den stock um zu sscanfx, und nutze das für diese Abfragen.


    Der "u" Parameter von sscanf2 (Pluginversion) funktioniert bei mir nicht.
    Wie viel langsamer / resourcenfressender würde der Server werden, wenn ich den stock mitnutze?

    Mit freundlichem Gruß
    Weper

  • Der "u" Parameter von sscanf2 (Pluginversion) funktioniert bei mir nicht.
    Wie viel langsamer / resourcenfressender würde der Server werden, wenn ich den stock mitnutze?


    Gut, das ist sscanf, meine Meinung darüber ist ja bekannt.


    Das ist so wenig, das kannst du vernachlässigen.


    Ich würde dir aber raten, anstatt den sscanf stock zu verwenden, und darauf verzichten zu müssen, den Spieler-Namen eingeben zu können, lieber strtok zu nutzen.


    dcmd_befehl(playerid,params[])
    {
    new pID, tmp[20], idx;
    tmp = strtok(params, idx);
    if(!strlen(tmp)) return SendClientMessage(playerid,0xFF0000FF,"Fehler: /befehl [playerid/SpielerName]");
    if(IsNumeric(tmp)) pID = strval(tmp);
    else pID = ReturnPlayerID(tmp);
    if(!IsPlayerConnected(pID)) return SendClientMessage(playerid,0xFF0000FF,"Der Spieler ist nicht online");

    //Code hier.
    return 1;
    }


    Funktionen die du brauchst
    stock strtok(const string[], &index) //©Jeffry
    {
    new result[20], length = strlen(string), i = index;
    while ((i < length) && (string[i] == ' ')) i++;
    strmid(result,string,i,((index = strfind(string, " ", false, i)) == -1) ? (index = length) : (index) , 20);
    index++;
    return result;
    }

    Funktionen die du brauchst
    stock ReturnPlayerID(l_PlayerName[]) //©Jeffry
    {
    new l_name[MAX_PLAYER_NAME];
    for(new i = 0; i < MAX_PLAYERS; i++)
    {
    if(GetPlayerName(i, l_name, MAX_PLAYER_NAME))
    {
    if(!strcmp(l_name,l_PlayerName, true)) return i;
    }
    }
    for(new i = 0; i < MAX_PLAYERS; i++)
    {
    if(GetPlayerName(i, l_name, MAX_PLAYER_NAME))
    {
    if(strfind(l_name,l_PlayerName,true)!=-1) return i;
    }
    }
    return INVALID_PLAYER_ID;
    }

    Funktionen die du brauchst
    stock IsNumeric(string[])
    {
    for (new i = 0, j = strlen(string); i < j; i++)
    {
    if ((string[i] > '9' || string[i] < '0')) return 0;
    }
    return 1;
    }


  • Benötige ich die 2te for Schleife oder vertuh ich mich grad. Die macht das 1zu1 das selbe wie die erste....


    Danke Jeffry: , dann werde ich das so einbauen.

    Mit freundlichem Gruß
    Weper

  • Nein, schau mal genau hin, die macht nicht 1:1 das gleiche. Die erste Schleife prüft erst, ob du den gesamten Namen eingegeben hast, die zweite überprüft, ob du einen Teil davon eingegeben hast.
    Das ist wichtig, wenn du folgendes Szenario hast:


    ID1: TestUser
    ID2: Test


    Jetzt gibst du /befehl Test ein. Das heißt, da du den ganzen Namen eingegeben hast, willst du ID 2 ansprechen. Ohne die Aufteilung, würde er dir (bei nur strfind) ID 1 ausgeben.
    Nimmst du nur strcmp, kannst du nicht "/befehl TestU" eingeben.



    EDIT:

    TomatenvondenAugennehm:


    :good:

    3HZXdYd.png

    Einmal editiert, zuletzt von Jeffry ()