shape1
shape2
shape3
shape4
shape7
shape8

String и как же его правильно считать


Mike_World

Освоившийся
Пользователь
31.12.2016
1
23
0
Приветствую форумчане и тех кто хочет научиться PAWN скриптингу.
Рекомендую ознакомиться с данным учебником (*клик*).
И после этого приступать к ознакомлению написания различных команд.
Так-же рекомендую не копировать готовую команду, а писать самому(подсматривая), никто не запрещает вам подсматривать, пишите, запоминайте, и у вас все получится.
 
Я решил написать данный урок, так как почти в каждом моде вижу одно и тоже, к примеру создам обычную команду для видимости ошибок оптимизаторов так скажем:
 
CMD:mystats(playerid, params[])
{
if(logged[playerid] == 1)
{
new string[255];
format(string, sizeof(string),
"{FFFF00}Статистика игрока: %s",
GN(playerid),
SPD(playerid, 25, MSGBOX,
"Статистика персонажа",
string,
"ОК","");
}
else
{
SCM(playerid, -1, "[X]Вы не авторизованы!");
}
return 1;
}

Теперь давайте его оптимизируем. Делаем это так. Смотрим для начала на строку:
format(string, sizeof(string),
"{FFFF00}Статистика игрока: %s", ... );

Считаем количество символов в " " (кавычках). В данном случае у нас их 29. Отсюда пишем такую простенькую формулу:

new string[29 + MAX_PLAYER_NAME - 2];

В итоге у нас получиться:

CMD:mystats(playerid, params[])
{
if(logged[playerid] == 1)
{
new string[29 + MAX_PLAYER_NAME - 2];
format(string, sizeof(string),
"{FFFF00}Статистика игрока: %s",
GN(playerid),
SPD(playerid, 25, MSGBOX,
"Статистика персонажа",
string,
"ОК","");
}
else
{
SCM(playerid, -1, "[X]Вы не авторизованы!");
}
return 1;
}

Да, и еще момент. Я знаю что есть те, кто думает: "Если я напишу в string[MAX_PLAYER_NAME], то стринг возьмет столько ячеек, сколько символов в нике." - это мнение ошибочно!

MAX_PLAYER_NAME - это #define инклюда a_samp. Выглядит он вот так:

#define MAX_PLAYER_NAME (24)

Да, мы могли написать даже вот так эту формулу:

new string[29 + 24 - 2];

Но согласитесь, удобнее вот так:

new string[29 + MAX_PLAYER_NAME - 2];
Теперь, вопрос-ответ:

Вопрос: зачем тебе в этой формуле "-2" ?

Ответ: "-2" - это мы откидываем из нашего формата вот эти символы "%s" и тому подобное, если бы там было написано следующее:

format(string, sizeof(string),
"{FFFF00}Статистика игрока: %s[ID:%d]", ...);
То мы бы писали формулу таким образом:

new string[29 + MAX_PLAYER_NAME - 4]; // ну думаю теперь понятно =)

Да и еще, вот пока писал, придумал наглядную схему для вас:

new string[кол-во символов в формате + MAX_PLAYER_NAME - число формативных помощников]; 
Не помню как точно называются эти символы: %s %d %i. Назову их формативными помощниками. Если Вы помните, напишите в комменты =)

Спасибо за внимание друзья. Надеюсь я Вам чем то помог
 
Автор: я, Mike_World.


 
Последнее редактирование модератором:

ШУРИК

Освоившийся
Пользователь
26.05.2017
1
16
0
25
Хороший урок,уважаю держи краба :smile454:

 

LeonYT

Освоившийся
Пользователь
04.09.2016
56
15
0
25
Ну во первых очень странно полагать, что в статистике (из твоего кода) просто так выделено 255 ячеек. Почему? Во первых при разработке статистики я лично изначально выделяю большое кол-во ячеек для того, чтобы после достижения лимита просто его увеличивать. Чем это удобно? Не надо подсчитывать длину каждый раз. Можно после окончательного релиза сразу посчитать один раз нужное кол-во ячеек и всё.

new string[255];
format(string, sizeof(string),
"{FFFF00}Статистика игрока: %s",
GN(playerid),

Подсчёт строки у тебя сделан неверно, сейчас скажу почему.
Твой подсчёт сделан таким образом:

new string[29 + MAX_PLAYER_NAME - 2];

Правильный вариант:

new string[29+(-2+MAX_PLAYER_NAME)+1];

Отличие лишь в том, что я добавил 1 ячейку для завершающего нуль символа "\0", о существовании которого, видимо ты не подозревал.
Что это такое? Каждая строка это массив символов, а каждый массив завершается NULL'ом. Его ASCII код - "\0". Для чего это нужно? Это требуется для того, чтобы компилятор различал каждую строку и понимал где её конец.

Кроме всего прочего я заменил твоё + MAX_PLAYER_NAME - 2 на (-2+MAX_PLAYER_NAME). Зачем? Представь что тебе нужно указать несколько форматированных данных, а у тебя будет каша из + MAX_PLAYER_NAME - 2 + 19 - 2, которая при дальнейшем редактировании размерности любых данных, на которые ты ссылаешься при форматировании будет превращаться в долгие поиски (особенно при большом кол-ве данных).
Чем мой вариант лучше? Представь что нужно отредактировать большое кол-во данных, скобки будут более явно показывать на какой из конкретных спецификаторов ведётся расчёт.
Кстати по поводу их названия, на оф. вики SA-MP эти самые символы называются Specifier, я же называю их просто "спецификаторы".

Кстати, в теме ты мог-бы указать ещё и альтернативный способ подсчёта строк от Daniel_Cortez.

 
Последнее редактирование модератором: