When using double quotes ( " ), you're basically telling the compiler that it should terminate the string after each quote So the string is actually:
a, null, b, null ...
You should use single quotes ( ' ) for characters.
Code:
new const g_AllowNickCharacter [] = { "a", "b", "c" }
server_print("%s, %s, %c", g_AllowNickCharacter, g_AllowNickCharacter[0], g_AllowNickCharacter[0]);
->
Code:
new const g_AllowNickCharacter [] = { 'a', 'b', 'c' }
server_print("%s, %s, %c", g_AllowNickCharacter, g_AllowNickCharacter[0], g_AllowNickCharacter[0]);
Remember though, you have to terminate the string by putting null at the end or all functions will continue reading memory until it reaches 0, which could cause memory access runtime errors.
Code:
new const g_AllowNickCharacter [] = { 'a', 'b', 'c' }
public plugin_init() {
register_plugin("Test Plugin 5", "", "[ --{-@ ]");
server_print("%s, %s, %c", g_AllowNickCharacter, g_AllowNickCharacter[0], g_AllowNickCharacter[0]);
}
Code:
abcTest Plugin 5, abcTest Plugin 5, a
->
Code:
new const g_AllowNickCharacter [] = { 'a', 'b', 'c', 0 }
public plugin_init() {
register_plugin("Test Plugin 5", "", "[ --{-@ ]");
server_print("%s, %s, %c", g_AllowNickCharacter, g_AllowNickCharacter[0], g_AllowNickCharacter[0]);
}
Code:
new const g_AllowNickCharacter [] =
{
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
's', 't', 'u', 'v', 'x', 'z', '<', '>', ',',
'+', '*', ''', '?', '=', ')', '(', '/', '#',
'.', '-', ';', ':', '_', /* 'ç', */ '~', /*'' ? */
'!', '|', '\', '[', ']', '1', '2', '3', '4',
'5', '6', '7', '8', '9', '0', '@', 0 // <-- Important null to end the string.
}
You could just as well do
Code:
new const g_AllowNickCharacter [] = "abcdefghijklmnopqrstuvxz<>,+*'?=)(/#.-;:_~!|\[]1234567890@"
replace() will check for occurances, skip containi() and add upper case letters instead.
With all that said, you should check out an ASCII chart and try using direct character comparisons instead.
For example:
Code:
if ( 'a' <= string[i] <= 'z' )
// ...
And how do we do this the easy way? We sort the string real fast so we can find the combinations easily:
Code:
new g_AllowNickCharacter [] = "abcdefghijklmnopqrstuvxz<>,+*'?=)(/#.-;:_~!|\[]1234567890@";
server_print("unsorted: %s", g_AllowNickCharacter);
SortIntegers(g_AllowNickCharacter, sizeof g_AllowNickCharacter - 1);
server_print(" sorted: %s", g_AllowNickCharacter);
Code:
unsorted: abcdefghijklmnopqrstuvxz<>,+*'?=)(/#.-;:_~!|\[]1234567890@
sorted: !#'()*+,-./0123456789:;<=>?@[\]_abcdefghijklmnopqrstuvxz|~
And breaked down, this shows the groupings we can use:
Code:
/*
a-z
A-Z
0-9
!
#
'
()*+,-./
:;<=>?@
[\]
_
|
~
*/
That requires another way of replacing characters but a simple way is just using a buffer since the string is so small.
This way is the most efficient. There are a lot of comparisons, but replace inside a loop is loop inception. Don't get me started on replace_all. loop
3
Code:
new string1[32] = "abcåäöABC¤$123€%!";
new string2[32];
new a;
for ( new i ; i < sizeof string1 ; i++ ) {
if (
'a' <= string1[i] <= 'z' ||
'A' <= string1[i] <= 'Z' ||
'0' <= string1[i] <= '9' ||
string1[i] == '!' ||
string1[i] == '#' ||
string1[i] == '^'' || // ' <- Because the code wrapper on this page uses \ as control character while pawn uses ^
'(' <= string1[i] <= '/' ||
':' <= string1[i] <= '@' ||
'[' <= string1[i] <= ']' ||
string1[i] == '_' ||
string1[i] == '|' ||
string1[i] == '~'
)
string2[a++] = string1[i];
}
string2[a] = 0; // Don't forget to terminate.
server_print("string1: %s", string1);
server_print("string2: %s", string2);
Code:
string1: abc+Ñ+ñ+ÂABC-ñ$123Ôé¼%!
string2: abcABC123!
Now I know you're asking... "How could I improve this further?".
Well. Comparing a variable 12 times will make it read the value of that variable from the memory 12 times. With a simple switch(), you can reduce that to 1!
Code:
new string1[32] = "abcåäöABC¤$123€%!";
new string2[32];
new a;
for ( new i ; i < sizeof string1 ; i++ ) {
if ( IsAcceptable(string1[i]) )
string2[a++] = string1[i];
}
string2[a] = 0; // Don't forget to terminate.
server_print("string1: %s", string1);
server_print("string2: %s", string2);
}
IsAcceptable(c) {
switch (c) {
case 'a' .. 'z' : return 1;
case 'A' .. 'Z' : return 1;
case '0' .. '9' : return 1;
case '!' : return 1;
case '#' : return 1;
case '^'' : return 1; // ' <- Because the code wrapper on this page uses \ as control character while pawn uses ^
case '(' .. '/' : return 1;
case ':' .. '@' : return 1;
case '[' .. ']' : return 1;
case '_' : return 1;
case '|' : return 1;
case '~' : return 1;
}
return 0;
}
Code:
string1: abc+Ñ+ñ+ÂABC-ñ$123Ôé¼%!
string2: abcABC123!
Readability could be improved but I guess you get the point and can take necessary parts from these examples that will fit you best.
In the end, none of these methods are slow. There's no need to worry about using one over another.