Форум Pawn.Wiki - Воплоти мечту в реальность!: sscanf - Форум Pawn.Wiki - Воплоти мечту в реальность!

Перейти к содержимому

  • (3 Страниц) +
  • 1
  • 2
  • 3
  • Вы не можете создать новую тему
  • Вы не можете ответить в тему

sscanf v2.8.3 Оценка: ***** 1 Голосов

#1
Пользователь офлайн   Pa4enka 

  • Профессионал
  • Вставить ник
  • Раскрыть информацию
SSCANF PLUGIN

Автор: Y_Less
Перевод: Pa4enka


Для начала работы с плагином достаточно добавить эту строку в мод (прим. после a_samp) :

#include < sscanf2 >


Файлы с расширениям .dll [Windows], .so[Linux] в папку plugins, а .inc в pawno/include; [/indent]
В server.cfg пропишите следующее: plugins sscanf

Основной код выглядит следующим образом:

if(sscanf(params, "ui", giveplayerid, amount))
return SendClientMessage(playerid, 0xFF0000AA, !"Используй: /givecash <playerid> <кол-во>");


Вместе с тем следует отметить, что sscanf может быть использован для любой обработки текста. Например, ini-процессор может выглядеть следующим образом:

if(sscanf(szFileLine, "p<=>s[8]s[32]", szIniName, szIniValue))
print("Invalid INI format line");


Существует также альтернативное имя функции, чтобы избежать путаницы со стандартным sscanf:

if (unformat(params, "ui", giveplayerid, amount))
return SendClientMessage(playerid, 0xFF0000AA, !"Используй: /givecash <playerid> <кол-во>");


СПЕЦИФИКАТОРЫ

1. Базовые

Таблица [Показать]

2. Строки


Спецификатор "s" используется, как и раньше, для строк - но теперь они более продвинутые.

sscanf("hello 27", "si", str, val);

Результат : hello и 27

Используем:

sscanf("hello there 27", "si", str, val);

Результат: неудача т.к «there» не целое число.

Используем:

sscanf("hello there", "s", str);

Результат: hello there

Используем:

sscanf("hello there", "s ", str);
// прим.: после s пробел

Результат: hello

Вы также можете избежать части строки с "\\" - обратите внимание, что два обратных слэша используется компилятором как один:

sscanf("hello\\ there 27", "si", str, val);

Результат:
hello there
27


Обратите внимание, что эти примеры будут выдавать предупреждения в консоль сервера, так как новая версия имеет нововведения. Теперь нужно обязательно указывать размер массива:

new
    	str[32],
    	val;
sscanf("hello\\ there 27", "s[32]i", str, val);


Как вы можете видеть - спецификатор формата теперь содержит длину строки.

Ветка 2.10.*: Теперь вы можете воспользоваться именными константами для объявления длинны строки.

#define STR_SIZE 32
new str[STR_SIZE], val;
sscanf("hello\\ there 27", "s[" #STR_SIZE "]i", str, val);


3. Запакованные строки

z и Z возвращают упакованные строки. В остальном они идентичны s и S.

4. Массивы


new arr[5];
sscanf("1 2 3 4 5", "a<i>[5]", arr);


После “a” спецификатора в <> указывается тип спецификатора(смотри «Спецификаторы»). Приведенный выше код заполнит цифрами массив "arr".
Массивы могут быть объединены со строками, указав размер строки в тип массива:

a<s[10]>[12]

«На выходе» получим массив из 12 строк, каждая длиной до 10 символов (9 + NULL).

5. Энум [прим. Enum]


Это, возможно, наиболее мощное дополнением к sscanf. Обновления дает возможность определить структуру перечисления в пределах спецификатора строки и считывать любые данные прямо в него.

enum E_DATA
{
    	E_DATA_C,
    	Float:E_DATA_X,
    	E_DATA_NAME[32],
    	E_DATA_Z
}

main
{
    	new var[E_DATA];
    	sscanf("1 12.0 Bob c", "e<ifs[32]c>", var);
}

е - начало  "перечислений"
<- Запуск спецификации структуры перечислении
i - Целое число, соответствует E_DATA_C
f - Float, соответствует E_DATA_X
s [32] - строка 32 ячейки, соответствует E_DATA_NAME
c - символ, соответствует E_DATA_Z
> - Конец спецификации перечислений


Большинство, но не все, спецификаторы могут быть использованы внутри перечислений (в частности, массивов).

6. Динамическая длинна (ветка 2.10.*)

И строки, и массивы имеют длину, обычно указываемую в строке с помощью (скажем) s [32]. Однако у этой системы есть некоторые крайние ограничения - в первую очередь макросы. Этот код работать не будет:

#define LEN 32
sscanf(params, "s[LEN]", str);


Этот код будет работать:

#define LEN 32
sscanf(params, "s["#LEN"]", str);


Но этот код даже не компилируется:

#define LEN (32)
sscanf(params, "s["#LEN"]", str);


Этот код будет работать, но это мягко говоря неудобно:

sscanf(params, "s[(32)]", str);


Этот код будет компилироваться, но тоже не будет работать:

#define LEN 8*4
sscanf(params, "s["#LEN"]", str);


По этой причине вы можете передавать длины строк и массивов в качестве дополнительных параметров, используя * для длины:

#define LEN 8*4
sscanf(params, "s[*]", LEN, str);


Длины отображаются ДО пункта назначения, сначала массивы, затем строки:

new int, arr[5][10], str[32];
sscanf(params, "ia<s[*]>[*]s[*]", int, sizeof (arr), sizeof (arr[]), arr, 32, str);


То же самое относится к строкам в перечислениях:

enum E_EXAMPLE
{
	Float:FLOAT,
	STR_1[32],
	STR_2[64],
	INT,
}

new dest[E_EXAMPLE];
sscanf(params, "e<fs[*]s[*]i>", _:STR_1 - _:FLOAT, 64, dest);


И для массивов пользователей:

new ids[3], i;
sscanf(params, "u[*]", sizeof (ids), ids);


Данное нововведения позволяет вам передавать переменную длину, если вы не хотите использовать всю строку, и использовать всю мощь препроцессора для генерации длин во время компиляции. Он также обходит ошибку компилятора в строковую форму с использованием скобок в строках. Теперь также используется * для всех строк и массивов, поэтому точно так же будет полностью использовать препроцессор.

7. Quiet


Два новых спецификатора"{" и "}" - строки, которые считываются и проверяются, но не сохраняются. Например:

sscanf("42 -100", "{i}i", var);

Очевидно, что есть два числа и два "i", но только одна переменная возврата. В итоге, первый “i" не сохранится, но повлияет на возвращаемое значение. Приведенный выше код будет равен: "var" -100".

8. Поисковые запросы


Строки, заключенные в одиночные кавычки (') проверяются на наличие в основной строке:

sscanf("10 11 woo 12", "i'woo'i", var0, var1);


Результат:

10
12


Вы можете достичь того же эффекта с:

sscanf("10 11 woo 12", "i{is[1000]}i", var0, var1);


9. Enums (ветка 2.10.*)

Функция, аналогичная quiet, которая позволяет вам пропустить перезапись определенных частей перечисления:

e<ii-i-ii>


Здесь "-" является "минусом" и сообщает sscanf, что там есть элемент перечисления, но ничего не делать, поэтому, если у вас есть:

enum E
{
    E_A,
    E_B,
    E_C,
    E_D,
    E_E
}


И вы хотели обновить только первые два и последнее поля и оставить все остальные нетронутыми, вы можете использовать этот спецификатор выше. Таким образом, sscanf знает, как пропускать память и сколько памяти пропускать. Обратите внимание, что это ничего не читает, поэтому вы также можете объединить это с quiet:

e<ii-i-i{ii}i>


Это прочитает два значения и сохранит их, пропустит две ячейки памяти, прочитает два значения и НЕ сохранит их, а затем прочитает и сохранит последнее значение. Таким образом, вы можете записать все значения для каждого слота в перечислении, но использовать только 3 из них. Обратите внимание, что то же самое и с E - если вы это сделаете:

E<ii-i-ii>


Вы должны указать ТОЛЬКО ТРИ значения по умолчанию, а не все пять:

E<ii-i-ii>(11, 22, 55)


10. Разделители


В предыдущей версии была эта функция. Но сейчас она изменила свой синтаксис. Раньше было:

sscanf("1,2,3", "p,iii", var0, var1, var2);


Сейчас:

sscanf("1,2,3", "p<,>iii", var0, var1, var2);

Старая версия разделителей будет доступна, но плагин сообщит вам, что нужно изменить ваш код согласно новому синтаксису.

Ветка 2.10.*: Теперь вы можете использовать необязательные разделители с помощью P (верхний регистр p для соответствия другим необязательным спецификаторам). Они не являются обязательными в том смысле, что вы указываете несколько разделителей, и любой из них может использоваться для завершения следующего символа:

sscanf("(4, 5, 6, 7)", "P<(),>{s[2]}iiii", a, b, c, d);


Здесь используется quiet, чтобы игнорировать все, что находится перед первым (, а затем использовать несколько разделителей для завершения всего текста. Пример:
sscanf("42, 43; 44@", "P<,;@>a<i>[3]", arr);


11. Необязательные спецификаторы


КАЖДЫЙ спецификатор формата (то есть, все, за исключением ''{} и р) теперь имеет дополнительный спецификатор, который пишется с заглавной буквы.

sscanf("", "I(12)", var);

В "()" s (круглые скобки) содержат значения по умолчанию для дополнительного целого числа и, как основная строка не содержит никаких данных, значение "вар" становится "12".

12. Пользователи («Users»)


"u", "q" и "R" спецификаторы поиска пользователя по имени или ID. Метод этого поиска изменился в последних версиях "sscanf".
Кроме того, "U", "Q" и "R", могут взять имя или идентификатор в качестве значения по умолчанию, и sscanf не будет пытаться определить, является ли этот ID online.

Раньше:

sscanf(params, "U(Y_Less)", id);
if (id == INVALID_PLAYER_ID)
{
     // Y_Less или введенный игрок не подключен.
}


Сейчас:

sscanf(params, "U(-1)", id);
if (id == -1)
{
    		// Ни один игрок не был введен.
}
else if (id == INVALID_PLAYER_ID)
{
    		// Введенный игрок не подключен.
}


Теперь пользователи могут при необходимости возвращать массив пользователей, а не только один. Этот массив представляет собой список совпадающих идентификаторов, а затем "INVALID_PLAYER_ID". Например, на сервере играют:
Ники игроков [Показать]


Код:

new ids[3], i;
if (sscanf("Le", "?<MATCH_NAME_PARTIAL=1>u[3]", ids)) print("Ошибка");
for (i = 0; ids[i] != INVALID_PLAYER_ID; ++i)
{
    if (ids[i] == cellmin)
    {
        print("Слишком много совпадений");
        break;
    }
    printf("id = %d", ids[i]);
}
if (i == 0) print("Совпадений не найдено")


Выведет:

id = 0
id = 1
Слишком много совпадений

Ищем «Les», получим:
id = 0 ; id = 1

И поиск без использования "MATCH_NAME_PARTIAL" даст:
Совпадений не найдено


12. Пользовательские спецификаторы


Последняя версия sscanf добавляет новый "К" спецификатор, чтобы позволить вам создавать свои собственные спецификаторы в PAWN:

SSCANF:playerstate(string[])
{
    if ('0' <= string[0] <= '9')
    {
        new
        ret = strval(string);
        if (0 <= ret <= 9)
        {
            	return ret;
        }
    }
    else if (!strcmp(string, "PLAYER_STATE_NONE")) return 0;
    else if (!strcmp(string, "PLAYER_STATE_ONFOOT")) return 1;
    else if (!strcmp(string, "PLAYER_STATE_DRIVER")) return 2;
    else if (!strcmp(string, "PLAYER_STATE_PASSENGER")) return 3;
    else if (!strcmp(string, "PLAYER_STATE_WASTED")) return 7;
    else if (!strcmp(string, "PLAYER_STATE_SPAWNED")) return 8;
    else if (!strcmp(string, "PLAYER_STATE_SPECTATING")) return 9;
}


Код выше добавит "playerstate" спецификатор, что позволяет сделать следующее:

sscanf(params, "uk<playerstate>", playerid, state);


Эта система поддерживает дополнительные пользовательские спецификаторы без дополнительного кода PAWN:

sscanf(params, "uK<playerstate>(PLAYER_STATE_NONE)", playerid, state);


ОПЦИИ

1. OLD_DEFAULT_NAME:


Поведение "U", "Q" и "R" были изменены, чтобы принять любое количество по умолчанию, вместо подключенного игрока.

2. MATCH_NAME_PARTIAL:


В настоящее время sscanf будет искать игроков по имени, и будет ВСЕГДА искать игрока, имя которого начинается с указанной строки. Если у вас есть, скажем, "[CLAN] Y_Less", и кто-то типа "Y_Less", sscanf не найдет "[CLAN] Y_Less", потому что имя не начинается с указанным именем.

3. CELLMIN_ON_MATCHES:

Вне зависимости от значения "MATCH_NAME_PARTIAL", первый найденный игрок всегда будет показан, так что если вы делаете поиск для "_" на сервере RP, вы можете получить практически любого человека. Для того, чтобы обнаружить более чем одного игрока, то sscanf возвращает идентификатор "cellmin":

sscanf(params, "?<CELLMIN_ON_MATCHES=1>U(-1)", id);
if (id == -1)
{
        // ничего не ввели
}
else if (id == cellmin)
{
       // найдено несколько игроков
}
else if (id == INVALID_PLAYER_ID)
{
       // Игрок не подключен
}
else
{
        // Найден 1(!) игрок
}


4. SSCANF_QUIET:

Не выводить какие-либо ошибки на консоль. На самом деле не рекомендуется, если вы не знаете, что ваш код является стабильным.

ОШИБКИ И ПРЕДУПРЕЖДЕНИЯ
Ошибки и предупреждения [Показать]





Специально для Pawn-Wiki.Ru!

Распространение без разрешения автора строго запрещено!


Оригинальная документация | Автор: Y_Less
extract | Автор: m1n1vv

Скачать последний релиз 2.8.*: sscanf-2.8.3.zip [55,14К]
Скачать последний релиз 2.10.*: sscanf-2.10.2.zip [70,46К]

Сообщение отредактировал Romzes: 17 марта 2023 - 02:57
Причина редактирования: fix таблицы

15

#2
Пользователь офлайн   Romzes 

  • ( ^_^ )
  • Вставить ник
  • Раскрыть информацию
1. Почему ссылки на скачивание нету? PS: Я добавил.
2. Почему нельзя было таблицу оформить на форуме, довольно красивей будет выглядеть нежели скриншот.

По теме: Все очень классно, молодец что потрудился и перевел. +
0

#3
Пользователь офлайн   Pa4enka 

  • Профессионал
  • Вставить ник
  • Раскрыть информацию

Просмотр сообщенияRomzes (18 декабря 2016 - 18:42) писал:

1. Почему ссылки на скачивание нету? PS: Я добавил.
2. Почему нельзя было таблицу оформить на форуме, довольно красивей будет выглядеть нежели скриншот.

По теме: Все очень классно, молодец что потрудился и перевел. +

Хотел, но пришлось отойти. С таблицей не разобрался.

На днях дополню новой информацией.

UPD: добавил полезные ссылки

Сообщение отредактировал Pa4enka: 18 декабря 2016 - 19:58

0

#4
Пользователь офлайн   Pa4enka 

  • Профессионал
  • Вставить ник
  • Раскрыть информацию
Добавлен пункт ошибки и предупреждения.

Сообщение отредактировал Pa4enka: 19 декабря 2016 - 17:31

0

#5
Пользователь офлайн   NOOBinator 

  • Новичок
  • Вставить ник
  • Раскрыть информацию
Инклуд не рабочий. (RunTime Error 19)
0

#6
Пользователь офлайн   .s2s.k 

  • Banned
  • Вставить ник
  • Раскрыть информацию

Просмотр сообщенияNOOBinator (04 января 2017 - 16:52) писал:

Инклуд не рабочий. (RunTime Error 19)


Да нууууууууууууу

#7
Пользователь офлайн   Pa4enka 

  • Профессионал
  • Вставить ник
  • Раскрыть информацию

Просмотр сообщенияNOOBinator (04 января 2017 - 16:52) писал:

Инклуд не рабочий. (RunTime Error 19)

Все работает. Перепроверил.

Сообщение отредактировал Pa4enka: 04 января 2017 - 17:19

0

#8
Пользователь офлайн   Const 

  • Знаток
  • Вставить ник
  • Раскрыть информацию
У тебя пару ошибок увидел в конце.
1) Не "extact", а "extract";
2) Не "Распространения", а "Распространение", так грамотней :happy:

Изображение
0

#9
Пользователь офлайн   Romzes 

  • ( ^_^ )
  • Вставить ник
  • Раскрыть информацию

Просмотр сообщенияNOOBinator (04 января 2017 - 16:52) писал:

Инклуд не рабочий. (RunTime Error 19)


Может быть вы используете инклуд без установленного плагина?
0

#10
Пользователь офлайн   NOOBinator 

  • Новичок
  • Вставить ник
  • Раскрыть информацию

Просмотр сообщенияRomzes (04 января 2017 - 21:08) писал:

Может быть вы используете инклуд без установленного плагина?

Нет, всё, как полагается.
0

Поделиться темой:


  • (3 Страниц) +
  • 1
  • 2
  • 3
  • Вы не можете создать новую тему
  • Вы не можете ответить в тему

1 человек читают эту тему
0 пользователей, 1 гостей, 0 скрытых пользователей


Яндекс.Метрика