[Tutorial] How to use strcmp
#1

Recently, i have seen many people using strcmp in a way that it wasnt really made for, command processing being one of them. I am writing this tutorial (my first) to explain how, why and when to use strcmp, and when not to. There is a page on the SAMP wiki about strcmp, but it really does not go into the depth of detail required in my opinion. You may also have seen my post in the Scripting Discussion section earlier about script timings, well that inspired me to write this thread, because it made me think about all the people using strcmp.

What does strcmp mean?
strcmp basically means string compare. It compares 2 strings against eachother.

strcmp - Usage
strcmp is not a simple function. However it only requires 2 arguments in order for it to work as it should.

Arguments:
pawn Code:
(const string1, const string2)
They are the basic requirements of strcmp, however there are 2 more optional arguments that follow the 2 strings...
pawn Code:
bool:ignorecase (defaults to false), length (when length is set, it will only compare the 2 strings up to the "length" letter
- Those 2 arguments will follow the two requred ones.

strcmp can be used for comparing any strings.

What does strcmp return?
strcmp returns 3 different things, depending on the order of strings and whether they match, i have found that the wiki information is slightly incorrect.

If the two strings that you are comparing match, strcmp will return 0. If they dont match, they will return either -1 or 1, depending on the way you have your strings postioned (first or second place).

For example...
pawn Code:
strcmp("funky", "funky");
will return 0. Both strings match.

The use of strcmp when comparing a string from a file (using the native file functions) is slightly different, you have to remember that the native file functions will also read any "\{}" operators. Such as "\n" and "\r" - so the strings that are compared from a file will include \n and \r - if you are using the native file functions, remember to take this into account when writing your script.

strcmp and Command Processing
strcmp and Command Processing, in my opinion is a big no no. It is slower than every other command processor that has been developed. strcmp can be used very well for comparing cmdtext to the command you want, but its not the best method by no means.

Take DCMD for example, a quick and easy to use command processor, allowing command processing practically outside of the script, you could use an include to store what the command will do, it is also alot fast than strcmp, it is also a lot tidier to script with...

Here is the strcmp version of command processing (even though its not a command processing)
pawn Code:
public OnPlayerCommandText(playerid, cmdtext[])
{
     if(!strcmp("/test", cmdtext))
     {
         print("Hello");
         return 1;
     }
     return 0;
}
And now the dcmd version... (dont forget to add your DCMD macro to the top)
pawn Code:
public OnPlayerCommandText(playerid, cmdtext[])
{
     dcmd(test, 4, cmdtext);
     return 0;
}

//The below sub section of script, can be added in either the script, and include (or maybe even as a plugin, but ive never tried it and wouldnt reccomend it)
dcmd_test(playerd, params[])
{
     print("Hello");
     return 1;
}
See the difference? DCMD is much much quicker than strcmp, and it is also much tidier as you can see.

strcmp and string sizing (aimed at use of 256)
This leads back to Y_Less' topic of "Why you should not use 256" which can be found here: https://sampforum.blast.hk/showthread.php?tid=55261

By now, you should already have understanding on how strcmp works, strcmp goes through every cell of both strings to find out if each cell matches. Think about the following script;
pawn Code:
new string[256];
GetPlayerName(playerid, string, sizeof(string));
Now lets say a players name is "Bobby" (dont ask)

Theres 256 cells just to contain "Bobby" - but - strcmp still has to go through all 256 cells to see if it matches the other string. Although strcmp practically disregards the empty cells when its comparing the 2 strings, it still needs to go through the 256 cells to find out if a cell is empty. Going through all these cells for nothing seems a bit pointless, but thats what you've told the script to do, and thats what it will do. You can read more on this on the "String Manipulation" documentation at the ITB CompuPhase website - A link is available at the end of the thread.

Hey! Remember that additional argument of "length"?
As i said above, strcmp compares all of whats in the string, no matter if the cell is blank. You can set the additional length argument, and strcmp will stop comparing after a set length. If you know that a string is going to be a set length, or that both strings are not going to be above a certain length, set that "certain length" as the length argument in strcmp. Then strcmp will stop comparing when it reaches the set maximum length.

NULL (-NULL) Credits to Y_Less & ITB CompuPhase PAWN "Language Guide"
Due to the way strings are understood in PAWN. Including the way they are manipulated within PAWN, strings finish at "NULL" (or "-NULL"). strcmp doesn't pass NULL or the length that was specified in the strcmp "length" argument. This means that if NULL is reached before the length then the string will not match, and so strcmp will not return 0.

It is also worth mentioning that if a strings length (strlen(string) == 0) then strcmp will also always return 0, so it will be worth checking a string for its length if you know it's length is not always set (maybe due to a command sent by a player with parameters)

if(text == "BlahBlah") or if("BlahBlah" == "BlahBlah")
I have recently seen people trying to do this:
pawn Code:
if(text == "BlahBlah") or if("BlahBlah" == "BlahBlah")
this will not work, this is what strcmp was made for in the first place! You can do this check on certain cells, like this:
pawn Code:
if(text[0] == 'w')
but you cannot do it on full strings. Most people find using strcmp hard, but it is an easy concept when you know how. Working with strings (and malipulating them to do what you want) is sometimes a hard task, but the above shows one of the ways not to do it.

--------------------

Hopefully, you can now understand strcmp better than you did before, there's not much more that can be understood about strcmp, it is a very easy thing to get your head round, when you understand (or at least have read) the string manipulation documentation available on the CompuPhase website.

External Links:
The Official ITB CompuPhase PAWN HomePage: http://www.compuphase.com/pawn/pawn.htm
String Manipulation Documentation: http://www.compuphase.com/pawn/String_Manipulation.pdf

Special Thanks to;
Y-Less (about the 256 topic)
bigcomfycouch (Replying to the Timing Scripts... thread)
SA-MP Team (making it all possible)
Reply
#2

Quote:
Originally Posted by funky1234
View Post
pawn Code:
new string[256];
GetPlayerName(playerid, string, sizeof(string));
Special Thanks to;
Y-Less (about the 256 topic)
Fail. You use 256 size cells, yet you're reffering to Y_Less' topic, where he was explaining why NOT to use 256. This isn't a very good idea for new PAWN coders.
Reply
#3

Quote:
Originally Posted by [FU]Victious
View Post
Fail. You use 256 size cells, yet you're reffering to Y_Less' topic, where he was explaining why NOT to use 256. This isn't a very good idea for new PAWN coders.
I was explaining why NOT to use it, if you'd of read it, you'd of seen.
Read the whole section, then you'll see why i used it.

Quote:

strcmp and string sizing (aimed at use of 256)
This leads back to Y_Less' topic of "Why you should not use 256" which can be found here: https://sampforum.blast.hk/showthread.php?tid=55261

By now, you should already have understanding on how strcmp works, strcmp goes through every cell of both strings to find out if each cell matches. Think about the following script;
pawn Code:

new string[256];
GetPlayerName(playerid, string, sizeof(string));

Now lets say a players name is "Bobby" (dont ask)

Theres 256 cells just to contain "Bobby" - but - strcmp still has to go through all 256 cells to see if it matches the other string. Although strcmp practically disregards the empty cells when its comparing the 2 strings, it still needs to go through the 256 cells to find out if a cell is empty. Going through all these cells for nothing seems a bit pointless, but thats what you've told the script to do, and thats what it will do. You can read more on this on the "String Manipulation" documentation at the ITB CompuPhase website - A link is available at the end of the thread.

Reply
#4

Quote:
Originally Posted by [FU]Victious
View Post
Fail. You use 256 size cells, yet you're reffering to Y_Less' topic, where he was explaining why NOT to use 256. This isn't a very good idea for new PAWN coders.
Please learn to read. He was referring that if YOU have 256 cells, strcmp has to check all those 256. Were it should just be a maximum number of 24.

Again, read.
Reply
#5

I fail. Didn't read the Bobby bit
Reply
#6

I hope that you realize, dcmd also uses strcmp... it's in the definition.

pawn Code:
#define dcmd(%1,%2,%3) if ((strcmp((%3)[1], #%1, true, (%2)) == 0) && ((((%3)[(%2) + 1] == 0) && (dcmd_%1(playerid, "")))||(((%3)[(%2) + 1] == 32) && (dcmd_%1(playerid, (%3)[(%2) + 2]))))) return 1
Reply
#7

Quote:
Originally Posted by JaTochNietDan
View Post
I hope that you realize, dcmd also uses strcmp... it's in the definition.

pawn Code:
#define dcmd(%1,%2,%3) if ((strcmp((%3)[1], #%1, true, (%2)) == 0)
Yes, i considered that when i wrote the tutorial, but they way dcmd handles itself is still quicker than strcmp. I may update with a speed test later. - Because it limits the comparing length of strcmp (it limits it using the "length" argument)

dcmd(%1,%2,%3) if ((strcmp((%3)[1], #%1, true, (%2)) == 0)
Reply
#8

Quote:
Originally Posted by funky1234
View Post
Yes, i considered that when i wrote the tutorial, but they way dcmd handles itself is still quicker than strcmp. I may update with a speed test later.
Well maybe you should explain to people why dcmd is better, and why zcmd is better, there's not much use telling someone not to use strcmp as a command processor but instead use dcmd, when dcmd uses strcmp!
Reply
#9

I've just edited my post before yours, and ill add zcmd in now, i completely forgot about that while writing this thread

Thanks
Reply
#10

So why can't you do that in OnPlayerCommandText using strcmp directly to compare the cmdtext array to the command string and defining the length of the command? You make it sound like strcmp is a bad function that should never be used
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)