Доброе время суток, участники форума. Достаточно часто пользуюсь функцией sscanf. Почему? Она удобна и практична. Причем использовать ее можно не только в командах, но и, например, при загрузке чего-либо из базы данных, как это делаю я. Допустим, есть система автомобилей. Дабы не создавать два столбца для каждого из двух возможных цветов транспортного средства, можно создать один, в который записывать значение вида «цвет_1, цвет_2». Записать-то запишем, через format:
[code]format(строка, размер строки, «%d,%d», цвет_1, цвет_2);
Но вот получить из этой строки два значения уже будет проблематично. Приходит нам на помощь sscanf2. [url=http://danilasar.ru/viewtopic.php?f=21&t=130]Данный плагин уже опубликован на нашем Форуме.
Итак, функция имеет следующие аргументы:
[code]sscanf(откуда, «<разделитель>типы извлекаемых данных», куда_1, куда_2, …);
По поводу разделителей. Собственно, это тот символ, которым Вы разделяете введенные данные. Например, если аргументы записаны через запятую, тогда разделитель будет таким: <,>, если вертикальная палочка, <|>, если тире, <->, если пробел, < >. Если у Вас разделителем выступает пробел, тогда < > можно и вовсе не писать.
Что касается типов извлекаемых данных… Есть всего 4 типа:
[list][*]i, d — целые числа (например, «1», «-10», «120»);
[*]s[размер] — строка (например, «Форум», «Да», «PW»);
[*]f — дробные числа (например, «17.575», «-47.8», «100.99»);
[*]u — ID игрока или часть имени (например, «0», «1», «Vasya_Pet», «Vasya_Petrov»);
[size=150]Пример 1.
Вернемся к начальному примеру использования sscanf. В переменную string записаны два цвета: color1 и color2 через запятую. Нам нужно каждый из них увеличить на единицу (инкрементировать). Для этого сначала нужно получить каждый цвет из строки, а затем увеличивать их на единицу. Поскольку цвета имеют целочисленный тип данных, создаем две переменные типа integer:
new color1, color2;
Извлекаем оба цвета, записанных через запятую, из переменной string:
[code]sscanf(string, «p<,>dd», color1, color2);
Но лучше сделать так, если хотите создать меньшую нагрузку на систему:
[code]format(string, sizeof(string), «%d, %d», color1++, color2++);
[size=150]Пример 2.
Извлечем из переменной string три аргумента: UNIX время выдачи бана часа, UNIX время истечения бана чата и причину выдачи. Они записаны через пробел. UNIX время в обеих случаях приобретает целочисленный тип данных, а вот причина — строковый. Следовательно, выглядеть будет так: dds[100]. 100 я указал для примера. Допустим, максимальная длина причины не должна превышать 100 символов. В целом это будет выглядеть так:
[code]new argument1, argument2, argument3[100];
sscanf(string, «dds[100]», argument1, argument2, argument3);
[size=150]Пример 3.
Создаем команду телепортации по указанным координатам. Допустим, координаты записаны через запятую в переменной string. В этом случае наш sscanf примет следующий вид:
[code]new Float:x, Float:y, Float:z;
sscanf(string, «p<,>fff», x, y, z);
[size=150]Пример 4.
Ситуация посложнее. В переменную записаны дата и время какого-либо события: «2017-05-25 22:00». Сначала нужно извлечь три аргумента целочисленного типа, записанных через тире, а затем два аргумента целочисленных типов, записанных через двоеточие:
[code]new argument1, argument2, argument3, argument4, argument5;
sscanf(string, «p<->dddp<:>dd», argument1, argument2, argument3, argument4, argument5);
Ну и тогда в argument1 попадет 2017, в argument 2 — 05, в argument3 — 25, в argument 4 — 22, в аргумент 5 — 00.
[b]Будет полезно при использовании данной функции в командах:
sscanf возвращает значение 0. Это значит, что для проверки, удалось ли найти все указанные аргументы нужно писать:
[code]if(sscanf(string, «типы данных», argument1, … argumentn)) return SendClientMessage(playerid, 0xFF0000FF, «Аргументы не найдены.»);
и, соответственно,
[code]if(!sscanf(string, «типы данных», argument1, … argumentn)) return SendClientMessage(playerid, 0xFF0000FF, «Аргументы найдены.»);
Пример команды /goto. Можно вводить координаты, можно вводить ID игрока, а можно просто ничего не вводить и телепортироваться на заданные кодом координаты:
[code]CMD:goto(playerid, params[])
{
if(!strlen(params))//Если пользователь вообще ничего не ввел, телепортируем его по координатам, указанным ниже
return SetPlayerPos(playerid, ваша_координата_х, ваша_координата_y, ваша_координата_z);
new Float:x, Float:y, Float:z;//Создаем три новые переменные дробного типа, куда впоследствии запишем координаты игроков
if(!sscanf(params, «u», params[0]))//Если пользователь ввел одно целое число, скорее всего являющееся идом игрока:
{
if(params[0] == INVALID_PLAYER_ID)//Проверяем, в сети ли игрок
return SendClientMessage(playerid, 0xFF0000FF, «Указанный вами игрок не в сети»);
GetPlayerPos(params[0], x, y, z);//Получаем позицию указанного игрока
SetPlayerPos(playerid, x, y, z);//Изменяем позицию нашу на позицию указанного игрока
return true;
}
if(!sscanf(params, «p<,>fff», x, y, z)//Проверяем, найдены ли три координаты дробного типа, записанные через запятую, в строке
return SetPlayerPos(playerid, x, y, z);//Если найдены, телепортируем на них игрока
return true;
}
Собственно это все.
Автор: Elrmrnt-Kritik