Добро пожаловать на Pro Pawn - Портал о PAWN-скриптинге.
Показано с 1 по 5 из 5
  1. #1
    Аватар для DmitriyVasilev
    Пользователь

    Статус
    Оффлайн
    Регистрация
    01.01.2019
    Сообщений
    86
    Репутация:
    0 ±

    Вопрос про sscanf.

    Здравствуйте, почему в одной команде просто назначен sscanf а в другой
    1. new giveplayerid;
    2. if(sscanf(params, "u",giveplayerid)) return SCM(playerid, -1, !"Введите: /iwep [playerid]");

    зачем объявлять переменную?

  2. #2
    Аватар для Seviel
    Пользователь

    Статус
    Оффлайн
    Регистрация
    23.12.2016
    Адрес
    Казахстан
    Сообщений
    148
    Репутация:
    26 ±
    В giveplayerid будет храниться id игрока.

    u - user, он может быть указан с помощью id(например: 15) или часть ника(например: Nick).

  3. #3
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    Цитата Сообщение от DmitriyVasilev Посмотреть сообщение
    Здравствуйте, почему в одной команде просто назначен sscanf а в другой
    1. new giveplayerid;
    2. if(sscanf(params, "u",giveplayerid)) return SCM(playerid, -1, !"Введите: /iwep [playerid]");

    зачем объявлять переменную?
    Потому что в первом случае используется параметр params для хранения данных, в котором просто может не оказаться ячеек. Для params выделяется столько ячеек, сколько символов ввёл игрок в качестве параметров. И если, например, написать такую команду:
    1. CMD:test(playerid, params[])
    2. {
    3. if(sscanf(params, "I(-1)", params[0]))// Если игрок не ввёл число, то sscanf попытается автоматически подставить "-1"
    4. return SendClientMessage(...);
    5. ....
    6. return 1;
    7. }

    То, если ввести "/test", команда не выполнится, так как случится выход за пределы массива, ибо мы никаких параметров не передали с командой => в params не существует нулевой ячейки.

    Или если, например, попытаться записать текст из параметра, который находится не напоследнем месте. Например:
    1. CMD:test(playerid, params[])
    2. {
    3. if(sscanf(params, "s[30]ii", params[0], params[1], params[2]))
    4. return SendClientMessage(...);
    5. ....
    6. return 1;
    7. }

    Если ввести "/test Привет 11 62", то sscanf сначала запишет слово "Привет" в ячейки с нулевой по пятую, а потом перезапишет первую и вторую ячейку указанными числами, портя записанное ранее слово (это довольно распространённая проблема у любителей не объявлять переменные для хранения параметров).
     При обработке "s[30
    "]
    1. 0 - П
    2. 1 - р
    3. 2 - и
    4. 3 - в
    5. 4 - е
    6. 5 - т
    7. 6 - \0


     При обработке "ii"
    1. 0 - П
    2. 1 - 11// Вот эти ячейки будут перезаписаны => данные уже испорчены и команда работает неправильно
    3. 2 - 62
    4. 3 - в
    5. 4 - е
    6. 5 - т
    7. 6 - \0



    Да и на читаемость это очень сильно влияет, ибо гораздо понятнее смысл передаваемых данных в таком случае:
    1. format(string, sizeof(string), "Игрок %s купил %s за $%d на слот %d", player_name, item_name, item_price, item_slot);

    Нежели чем в таком:
    1. format(string, sizeof(string), "Игрок %s купил %s за $%d на слот %d", player_name, params[2], params[0], params[1]);

    В первом случае достаточно посмотреть на имя переменной, чтоб понять какие данные там хранятся. Во втором случае нужно смотреть на строку, выискивать среди неё нужный заполнитель и сопоставлять "params[..]" с найденным заполнителем (либо вообще лезть в шапку команды и смотреть структуру sscanf).


    Если и использовать params для хранения параметров команды, то только в качестве хранения текста, по типу:
    1. CMD:pm(playerid, params[])
    2. {
    3. new giveplayerid;
    4. if(sscanf(params, "rs[128]", giveplayerid, params))// Запишем введённое сообщение в params
    5. return SendClientMessage(playerid, -1, "/pm id text");
    6. if(giveplayerid == INVALID_PLAYER_ID)
    7. return SendClientMessage(playerid, -1, "Игрок не найден!");
    8. SendClientMessage(giveplayerid, -1, params);// и отобразим его получателю
    9. return 1;
    10. }

    В этом случае и вышеперечисленных проблем не будет, и читаемость не сильно упадёт, ибо сразу понятно, что массив params хранит какой-то текст.
    Последний раз редактировалось DeimoS; 07.03.2019 в 23:17.
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

    Широко известно, что идеи стоят 0.8333 цента каждая (исходя из рыночной цены 10 центов за дюжину).
    Великих идей полно, на них нет спроса.
    Воплощение идеи в законченную игру требует долгой работы,
    таланта, терпения и креативности, не говоря уж о затратах денег, времени и ресурсов.
    Предложить идею просто, воплотить – вот в чём проблема

    Steve Pavlina

  4. Пользователь сказал cпасибо:
    DmitriyVasilev (08.03.2019)
  5. #4
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от DeimoS Посмотреть сообщение
    И если, например, написать такую команду:
    1. CMD:test(playerid, params[])
    2. {
    3. if(sscanf(params, "I(-1)", params[0]))// Если игрок не ввёл число, то sscanf попытается автоматически подставить "-1"
    4. return SendClientMessage(...);
    5. ....
    6. return 1;
    7. }

    То, если ввести "/test", команда не выполнится так как случится выход за пределы массива, ибо мы никаких параметров не передали с командой => в params не существует нулевой ячейки.
    В любой строке есть как минимум символ '\0', поэтому в массиве params всегда гарантируется наличие 0-й ячейки.
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  6. 2 пользователя(ей) сказали cпасибо:
    DeimoS (08.03.2019) DmitriyVasilev (08.03.2019)
  7. #5
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    В любой строке есть как минимум символ '\0', поэтому в массиве params всегда гарантируется наличие 0-й ячейки.
    Да, точно. Забыл про нуль-символ. Ну сути это не меняет и пример тогда будет таким:
    1. CMD:test(playerid, params[])
    2. {
    3. if(sscanf(params, "I(-1)I(-1)", params[0], params[1]))// Если игрок не ввёл число, то sscanf попытается автоматически подставить "-1"
    4. return SendClientMessage(...);
    5. ....
    6. return 1;
    7. }
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

    Широко известно, что идеи стоят 0.8333 цента каждая (исходя из рыночной цены 10 центов за дюжину).
    Великих идей полно, на них нет спроса.
    Воплощение идеи в законченную игру требует долгой работы,
    таланта, терпения и креативности, не говоря уж о затратах денег, времени и ресурсов.
    Предложить идею просто, воплотить – вот в чём проблема

    Steve Pavlina

 

 

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •