Введение. Основная информация.
Доброе время суток, участники форума. Достаточно часто пользуюсь функцией sscanf. Почему? Она удобна и практична. Причем использовать ее можно не только в командах, но и, например, при загрузке чего-либо из базы данных, как это делаю я. Допустим, есть система автомобилей. Дабы не создавать два столбца для каждого из двух возможных цветов транспортного средства, можно создать один, в который записывать значение вида «цвет_1, цвет_2». Записать-то запишем, через format:
[code]format(строка, размер строки, «%d,%d», цвет_1, цвет_2);[/code]
Но вот получить из этой строки два значения уже будет проблематично. Приходит нам на помощь sscanf2. [url=http://danilasar.ru/viewtopic.php?f=21&t=130]Данный плагин уже опубликован на нашем Форуме.[/url]
Итак, функция имеет следующие аргументы:
[code]sscanf(откуда, «<разделитель>типы извлекаемых данных», куда_1, куда_2, …);[/code]
По поводу разделителей. Собственно, это тот символ, которым Вы разделяете введенные данные. Например, если аргументы записаны через запятую, тогда разделитель будет таким: <,>, если вертикальная палочка, <|>, если тире, <->, если пробел, < >. Если у Вас разделителем выступает пробел, тогда < > можно и вовсе не писать.
Что касается типов извлекаемых данных… Есть всего 4 типа:
[list]

  • [*]i, d — целые числа (например, «1», «-10», «120»);

  • [*]s[размер] — строка (например, «Форум», «Да», «PW»);

  • [*]f — дробные числа (например, «17.575», «-47.8», «100.99»);

  • [*]u — ID игрока или часть имени (например, «0», «1», «Vasya_Pet», «Vasya_Petrov»);
  • [/list]
    [size=150]Пример 1.[/size]
    Вернемся к начальному примеру использования sscanf. В переменную string записаны два цвета: color1 и color2 через запятую. Нам нужно каждый из них увеличить на единицу (инкрементировать). Для этого сначала нужно получить каждый цвет из строки, а затем увеличивать их на единицу. Поскольку цвета имеют целочисленный тип данных, создаем две переменные типа integer:
    new color1, color2;
    Извлекаем оба цвета, записанных через запятую, из переменной string:
    [code]sscanf(string, «p<,>dd», color1, color2);[/code]
    Но лучше сделать так, если хотите создать меньшую нагрузку на систему:
    [code]format(string, sizeof(string), «%d, %d», color1++, color2++);[/code]
    [size=150]Пример 2.[/size]
    Извлечем из переменной string три аргумента: UNIX время выдачи бана часа, UNIX время истечения бана чата и причину выдачи. Они записаны через пробел. UNIX время в обеих случаях приобретает целочисленный тип данных, а вот причина — строковый. Следовательно, выглядеть будет так: dds[100]. 100 я указал для примера. Допустим, максимальная длина причины не должна превышать 100 символов. В целом это будет выглядеть так:
    [code]new argument1, argument2, argument3[100];
    sscanf(string, «dds[100]», argument1, argument2, argument3);[/code]

    [size=150]Пример 3.[/size]
    Создаем команду телепортации по указанным координатам. Допустим, координаты записаны через запятую в переменной string. В этом случае наш sscanf примет следующий вид:
    [code]new Float:x, Float:y, Float:z;
    sscanf(string, «p<,>fff», x, y, z);[/code]

    [size=150]Пример 4.[/size]
    Ситуация посложнее. В переменную записаны дата и время какого-либо события: «2017-05-25 22:00». Сначала нужно извлечь три аргумента целочисленного типа, записанных через тире, а затем два аргумента целочисленных типов, записанных через двоеточие:
    [code]new argument1, argument2, argument3, argument4, argument5;
    sscanf(string, «p<->dddp<:>dd», argument1, argument2, argument3, argument4, argument5);[/code]

    Ну и тогда в argument1 попадет 2017, в argument 2 — 05, в argument3 — 25, в argument 4 — 22, в аргумент 5 — 00.

    [b]Будет полезно при использовании данной функции в командах:[/b]
    sscanf возвращает значение 0. Это значит, что для проверки, удалось ли найти все указанные аргументы нужно писать:
    [code]if(sscanf(string, «типы данных», argument1, … argumentn)) return SendClientMessage(playerid, 0xFF0000FF, «Аргументы не найдены.»); [/code]
    и, соответственно,
    [code]if(!sscanf(string, «типы данных», argument1, … argumentn)) return SendClientMessage(playerid, 0xFF0000FF, «Аргументы найдены.»);[/code]
    Пример команды /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;
    }[/code]

    Собственно это все.
    Автор: Elrmrnt-Kritik

    От danilasar

    Это я

    Добавить комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *