ZCMD and SSCANF question with strcmp
#1

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.
Reply
#2

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.
Reply
#3

but if I want to use an integer in sscanf not string, like /note delete [note slot]

how can I do that?
Reply
#4

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...
Reply
#5

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]}
Reply
#6

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!
Reply
#7

but why 7 inside {s[7]}

And thanks, I'm starting to understand
Reply
#8

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.
Reply
#9

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..
Reply
#10

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.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)