ZCMD and SSCANF question with strcmp -
PaulDinam - 20.02.2013
I made this command:
Код:
CMD:note(playerid, params[])
{
new str[256];
if(!strcmp(params, "show", true))
{
SCM(playerid, COLOR_YELLOWG, "|____________Notes____________|");
format(str, sizeof(str), "Note 1: {94EDED}%s{FFFFFF}.", PlayerInfo[playerid][pNote1]);
SCM(playerid, -1, str);
format(str, sizeof(str), "Note 2: {94EDED}%s{FFFFFF}.", PlayerInfo[playerid][pNote2]);
SCM(playerid, -1, str);
format(str, sizeof(str), "Note 3: {94EDED}%s{FFFFFF}.", PlayerInfo[playerid][pNote3]);
SCM(playerid, -1, str);
SCM(playerid, COLOR_YELLOWG, "|_____________________________|");
format(str, sizeof(str), "* %s takes out a few paper notes and looks through them.", GetNameWithMask(playerid));
ProxDetector(30.0, playerid, str, COLOR_PURPLE);
}
if(!strcmp(params, "create", true))
{
new text[256];
if(sscanf(params,"s[256]",text)) return SyntaxMSG(playerid, "/note create [text]");
}
return 1;
}
When I do /note create it doesn't show me the SyntaxMSG..
how can I combine sscanf in strcmp with ZCMD.
Re: ZCMD and SSCANF question with strcmp -
Scenario - 20.02.2013
Multiple-parameter commands has always been something that most people don't understand. This is what I do, and it works fine...
pawn Код:
CMD:ban(playerid, params[])
{
new
szOption[7],
iTemp,
szReason[50]
;
if(sscanf(params, "s[7]U(-1)S(NULL)[50]", szOption, iTemp, szReason)) // you NEED TO SPECIFY ALL PARAMTERS (usually as optional, besides the first one) THE COMMAND WILL HAVE in the sscanf line here, otherwise, it won't work
return SendClientMessage(playerid, COLOR_WHITE, "SYNTAX: /ban [option] - OPTIONS: player, all");
if(!strcmp(szOption, "player", true))
{
if(sscanf(params, "{s[7]}us[50]", iTemp, szReason)) // notice the curly brackets ( { } ) around the first specifier? this tells sscanf that it's there, but we're not going to save the data from it
return SendClientMessage(playerid, COLOR_WHITE, "SYNTAX: /ban player [nick/id] [reason]");
if(iTemp == INVALID_PLAYER_ID)
return SendClientMessage(playerid, COLOR_RED, "ERROR: Invalid nick/ID.");
if(strlen(szReason) < 5 || strlen(szReason) > 50)
return SendClientMessage(playerid, COLOR_RED, "ERROR: The reason message must be at least 5 characters, but no more than 50!");
Ban(iTemp);
// send the message with szReason, blah blah
}
else if(!strcmp(szOption, "all", true))
{
// run a loop, ban all players, we can't put a reason here, the syntax won't allow it
}
else return SendClientMessage(playerid, COLOR_WHITE, "SYNTAX: /ban [option] - OPTIONS: player, all");
return 1;
}
* That is only pseudo code, I don't actually have a command like that. Read the comments for an explanation on the sscanf lines.
Re: ZCMD and SSCANF question with strcmp -
PaulDinam - 20.02.2013
but if I want to use an integer in sscanf not string, like /note delete [note slot]
how can I do that?
Re: ZCMD and SSCANF question with strcmp -
Scenario - 20.02.2013
Change the strcmp lines to check if the szOption = "delete"
If it does, change the sscanf line [inside of the strcmp statement] to:
pawn Код:
sscanf(params, "{s[7]}d", iTemp)
I made it easy to understand in my opinion...
Re: ZCMD and SSCANF question with strcmp -
PaulDinam - 20.02.2013
I made this:
Код:
CMD:note(playerid, params[])
{
new option[128], str[256], text[256];
if(sscanf(params,"s[128]",option)) return SyntaxMSG(playerid, "/note [show/create/remove/give]");
if(!strcmp(option, "show", true))
{
SCM(playerid, COLOR_YELLOWG, "|____________Notes____________|");
format(str, sizeof(str), "Note 1: {94EDED}%s{FFFFFF}.", PlayerInfo[playerid][pNote1]);
SCM(playerid, -1, str);
format(str, sizeof(str), "Note 2: {94EDED}%s{FFFFFF}.", PlayerInfo[playerid][pNote2]);
SCM(playerid, -1, str);
format(str, sizeof(str), "Note 3: {94EDED}%s{FFFFFF}.", PlayerInfo[playerid][pNote3]);
SCM(playerid, -1, str);
SCM(playerid, COLOR_YELLOWG, "|_____________________________|");
format(str, sizeof(str), "* %s takes out a few paper notes and looks through them.", GetNameWithMask(playerid));
ProxDetector(30.0, playerid, str, COLOR_PURPLE);
}
if(!strcmp(option, "create", true))
{
if(sscanf(params,"s[256]",text)) return SyntaxMSG(playerid, "/note create [text]");
}
return 1;
}
I don't understand this lol.
{s[7]}
Re: ZCMD and SSCANF question with strcmp -
Scenario - 20.02.2013
Check sscanf's release thread if you're still confused. I don't know how else to explain this...
pawn Код:
CMD:note(playerid, params[])
{
new
option[7], // this doesn't need to be 128 characters, "create" and "remove" are only 6 characters long!!
str[256]
;
if(sscanf(params,"s[7]",option))
return SyntaxMSG(playerid, "/note [show/create/remove/give]");
if(!strcmp(option, "show", true))
{
SCM(playerid, COLOR_YELLOWG, "|____________Notes____________|");
format(str, sizeof(str), "Note 1: {94EDED}%s{FFFFFF}.", PlayerInfo[playerid][pNote1]);
SCM(playerid, -1, str);
format(str, sizeof(str), "Note 2: {94EDED}%s{FFFFFF}.", PlayerInfo[playerid][pNote2]);
SCM(playerid, -1, str);
format(str, sizeof(str), "Note 3: {94EDED}%s{FFFFFF}.", PlayerInfo[playerid][pNote3]);
SCM(playerid, -1, str);
SCM(playerid, COLOR_YELLOWG, "|_____________________________|");
format(str, sizeof(str), "* %s takes out a few paper notes and looks through them.", GetNameWithMask(playerid));
ProxDetector(30.0, playerid, str, COLOR_PURPLE);
}
// if(!strcmp(option, "create", true)) // WRONG, use else if
if(!strcmp(option, "create", true))
{
/*if(sscanf(params,"s[256]",text))
return SyntaxMSG(playerid, "/note create [text]");*/
// ^^ Bad. This is the proper way. Remember, set your sting sizes to WHAT YOU NEED, not just random numbers.
new
szText[129] // the note text can only be 128 chars long
;
if(sscanf(params, "{s[7]}s[129]", szText)) // We use {s[7]} because sscanf reads params again, if we don't account for the "option", then it won't work. The {s[7]} says; "Hey, there's a specifer here, but we don't need to save it!"
return SyntaxMSG(playerid, "/note create [text]");
// finish the code
}
else if(!strcmp(option, "remove", true))
{
new
iNoteID
;
if(sscanf(params, "{s[7]}d", iNoteID))
return SyntaxMSG(playerid, "/note remove [note id]");
// finish the code, use iNoteID as the note's ID
}
return 1;
}
* Read the comments, they'll help!
Re: ZCMD and SSCANF question with strcmp -
PaulDinam - 20.02.2013
but why 7 inside {s[7]}
And thanks, I'm starting to understand
Re: ZCMD and SSCANF question with strcmp -
Scenario - 20.02.2013
Because, the 7 defines the specifier's length. Without this, sscanf
should return an error when you attempt to use it. You don't need 128/256 because none of the options you provided have a character length of over 6. You ALWAYS add +1 to the string size to account for the null terminator.
Re: ZCMD and SSCANF question with strcmp -
PaulDinam - 20.02.2013
It gives me a printf error:
sscanf warning: String buffer overflow.
And this doesn't work... what should I do?
It's the last question
Код:
CMD:note(playerid, params[])
{
new option[7],str[256];
if(sscanf(params,"s[7]",option)) return SyntaxMSG(playerid, "/note [show/create/remove/give]");
if(!strcmp(option, "show", true))
{
SCM(playerid, COLOR_YELLOWG, "|____________Notes____________|");
format(str, sizeof(str), "Note 1: {94EDED}%s{FFFFFF}.", PlayerInfo[playerid][pNote1]);
SCM(playerid, -1, str);
format(str, sizeof(str), "Note 2: {94EDED}%s{FFFFFF}.", PlayerInfo[playerid][pNote2]);
SCM(playerid, -1, str);
format(str, sizeof(str), "Note 3: {94EDED}%s{FFFFFF}.", PlayerInfo[playerid][pNote3]);
SCM(playerid, -1, str);
SCM(playerid, COLOR_YELLOWG, "|_____________________________|");
format(str, sizeof(str), "* %s takes out a few paper notes and looks through them.", GetNameWithMask(playerid));
ProxDetector(30.0, playerid, str, COLOR_PURPLE);
}
else if(!strcmp(option, "create", true))
{
new szText[129];
if(sscanf(params, "{s[7]}s[129]", szText)) return SyntaxMSG(playerid, "/note create [text]");
if(PlayerInfo[playerid][pNote1s] == 0)
{
strmid(PlayerInfo[playerid][pNote1], szText, 0, strlen(szText), 255);
PlayerInfo[playerid][pNote1s] = 1;
NoteMSG(playerid, "Note created successfuly.");
return 1;
}
else if(PlayerInfo[playerid][pNote2s] == 0)
{
strmid(PlayerInfo[playerid][pNote2], szText, 0, strlen(szText), 255);
PlayerInfo[playerid][pNote2s] = 1;
NoteMSG(playerid, "Note created successfuly.");
return 1;
}
else if(PlayerInfo[playerid][pNote3s] == 0)
{
strmid(PlayerInfo[playerid][pNote3], szText, 0, strlen(szText), 255);
PlayerInfo[playerid][pNote3s] = 1;
NoteMSG(playerid, "Note created successfuly.");
return 1;
}
else
{
NoteMSG(playerid, "You have no free pages left at your notebook.");
return 1;
}
}
else if(!strcmp(option, "remove", true))
{
new iNoteID;
if(sscanf(params, "{s[7]}d", iNoteID)) return SyntaxMSG(playerid, "/note remove [note id]");
switch(iNoteID)
{
case 1:
if(PlayerInfo[playerid][pNote1s] == 1)
{
strmid(PlayerInfo[playerid][pNote1], "None", 0, strlen("None"), 255);
PlayerInfo[playerid][pNote1s] = 0;
NoteMSG(playerid, "(slot 1) has been deleted successfuly.");
}
else
{
NoteMSG(playerid, "You don't have a note at slot 1.");
}
case 2:
if(PlayerInfo[playerid][pNote2s] == 1)
{
strmid(PlayerInfo[playerid][pNote2], "None", 0, strlen("None"), 255);
PlayerInfo[playerid][pNote2s] = 0;
NoteMSG(playerid, "(slot 2) has been deleted successfuly.");
}
else
{
NoteMSG(playerid, "You don't have a note at slot 2.");
}
case 3:
if(PlayerInfo[playerid][pNote3s] == 1)
{
strmid(PlayerInfo[playerid][pNote3], "None", 0, strlen("None"), 255);
PlayerInfo[playerid][pNote3s] = 0;
NoteMSG(playerid, "(slot 3) has been deleted successfuly.");
}
else
{
NoteMSG(playerid, "You don't have a note at slot 3.");
}
}
}
else if(!strcmp(option, "give", true))
{
new pid;
if(sscanf(params, "{s[7]}d", pid)) return SyntaxMSG(playerid, "/note give [playerid]");
}
return 1;
}
The freaking /note give [playerid] does not work, and it's the same as the others..
Re: ZCMD and SSCANF question with strcmp -
Scenario - 20.02.2013
The error has to be caused by something else- seems fine to me.
That isn't working because of this:
pawn Код:
if(sscanf(params, "{s[7]}dd", iNoteID, iNoteSlot)) return SyntaxMSG(playerid, "/note give [playerid] [slot]");
You didn't change the first d specifier, so it looks for a numerical value, not a player ID/name. So, change the first d specifier to u, and change iNoteID to iTargetID.