Перейти к содержанию
Авторизация  
LeonYT

Подсчёт размера строки

Рекомендуемые сообщения

LeonYT

Приветствую пользователей портала, просматривая темы я столкнулся с тем, что одно из самых часто используемых навыков в скриптинге (подсчёт строки) у некоторых или вообще не используется, или же используется с грубейшими ошибками. "Непорядок" - подумал я, и решил найти туториал о подсчёте строки, который я так и не нашёл  :D83DDE27:.
В итоге решил написать максимально подробный туториал о подсчёте строки, в котором освещу два способа подсчёта, каждый из которых будет иметь свои плюсы и минусы (о которых в конце).

Начнём пожалуй!

Способ первый (классический):

Давайте  напишу готовый код, который впоследствии разберу:

new string[28], apple = 200;
format(string, sizeof(string), "В ящике находится %d яблок", apple);
SCM(playerid, 0xFFFFFFFF, string);

Ну а теперь давайте разберёмся, каким образом я посчитал сам string
1) Считаем размер самой строки (которую форматируем), её размер 26 символов (26 ячеек)
2) Добавляем +1 ячейку для "нуль символа" - "\0" (NULL). 26+1 = 27
3) Вычитаем длину имеющихся в строке спецификаторов (%d, %s, %i и т.д.). У нас 1 спецификатор, длина которого 2 символа. 27-2 = 25
4) Прибавляем максимальную длину данных всех спецификаторов. Максимальное количество яблок в ящике - трёхзначное число. Выделяем 3 ячейки под это число. 25+3 = 28
Profit! Мы посчитали размер строки.

Для закрепления давайте посчитаем размер строки с несколькими спецификаторами:

new string[57], apple = 200, pear = 300;
format(string, sizeof(string), "В первом ящике находится %d яблок, а во втором %d груш", apple);
SCM(playerid, 0xFFFFFFFF, string);

/*
1) Считаем размер исходной строки: В первом ящике находится %d яблок, а во втором %d груш - 54 символа
2) Добавляем нуль символ: 54+1 = 55 ячеек
3) Вычитаем длину имеющихся спецификаторов (их два, каждый длиной в 2 символа): 55 - (2*2) = 51 ячейка
4) Прибавляем максимальную длину спецификаторов (их два, у каждого максимальная длина - 3 символа): 51+(3*2) = 57
Размер строки - 57 ячеек.

Давайте разберём его плюсы и минусы:
Плюсы:

• Привычность использования
• Удобно считать при надобности посчитать несколько строк в одном участке кода
• Новичкам проще понять данный метод
Минусы:
• Скорость подсчёта

• При дальнейшем изменении данных сложнее пересчитать размер

 

Способ второй (Автор: Daniel Cortez):

Данный способ лично я применяю для подсчёта размера MySQL запросов (потом по плюсам и минусам поймёте почему)
Давайте разберу готовый код:

static const fmt_str[] = "Ваш id: %d";
new string[sizeof(fmt_str) + (-2 + 3)];
format(string, sizeof(string), fmt_str, playerid);
SCM(playerid, 0xFFFFFFFF, string);

Давайте разберёмся как идёт подсчёт:
1) Сама исходная строка считается автоматически посредством 
sizeof(fmt_str)
2) Нуль символ считается автоматически при использовании sizeof
3) Спецификаторы считаются по формуле и прибавляются к текущей строке
Давайте разберём формулу: (-размер спецификатора+максимальная длина выводимых данных)
Длина спецификатора у нас - 2 символа (2 ячейки), а максимальная длина ID игрока в игре - 3 символа (3 ячейки), из этого получаем формулу: (-2+3)

Для наглядности и закрепления материала давайте разберу вариант с несколькими спецификаторами:

 

static const fmt_str[] = "Ваш id: %d, ваш IP: %s";
new string[sizeof(fmt_str) + (-2 + 3) + (-2 + 16)], ip[16];
GetPlayerIp(playerid, ip, sizeof(ip));
format(string, sizeof(string), fmt_str, playerid, ip);
SCM(playerid, 0xFFFFFFFF, string);

/*
Размер самой строки посчитан автоматически, нам требуется посчитать лишь размер спецификаторов
ID мы уже считали в предыдущем примере
IP посчитан также, изначальная длина спецификатора + максимальная длина выводимых данных. Максимальная длина IP - 16 символов
В итоге получаем формулу: исходная строка (-2 + 3) + (-2 + 16)
*/

Давайте разберём его плюсы и минусы:
Плюсы:
• Можно легко изменить размер строки при последующем изменении данных (нужно лишь поменять исходную строку и дополнить формулу)
• Скорость подсчёта

Минусы:

• Неудобство создания в местах кода, где необходимо несколько раз изменять строку

• Громоздкая конструкция кода (я советую делать готовую заготовку и вставлять её)


Вывод: Каждый из способов удобен и не удобен в конкретных ситуациях. Лично я использую первый способ везде кроме MySQL запросов. Какой использовать способ вам - решать только вам :-). Спасибо за внимание!

Автор: LeonYT

  • Like 4

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
SCRIPTMAN

Хороший урок, но можно немного улучшить.

static const fmt_str[] = "Ваш id: %d, ваш IP: %s";
new string[sizeof(fmt_str)-2+3-2+16], ip[16];
GetPlayerIp(playerid, ip, sizeof(ip));
format(string, sizeof(string), fmt_str, playerid, ip);
SCM(playerid, 0xFFFFFFFF, string);

fmt str - сокращенно - format string(форматированная строка).

static использовать гораздо лучше, я использую его везде, но и у него есть минусы..

Если вам нужно создать её один static, у вас будет выдавать ошибки, так как будет одинаковый он, для этого можно сделать так:

new apple = 1;
static const fmt_str_2[] = "Яблок в ящике: %d";
new string_2[sizeof(fmt_str_2)-2+1];
format(string_2, sizeof(string_2), fmt_str_2, apple);
SCM(playerid, 0xFFFFFFFF, string_2);

С текстом гораздо труднее.

1. Для начала считаем символы, записываем их как сказал LeonYT.

2. Дальше считаем весь текст, включая %s, %d и т.д..

4. Допустим, у нас получилось так:

static const fmt_str[] = "LeonYT сделал отличный урок, SCRIPTMAN сказал ему: %s, его ид: %d";
new string[sizeof(fmt_str)-2+сейчас будет считать текст-2+3];
format(string, sizeof(string), fmt_str, params[0], playerid);
SCM(playerid, 0xFFFFFFFF, string);

5. Считаем буквы, символы, получается 65(если не ошибаюсь)

6. Теперь к 65 прибавляем 3 = 68, то есть, еще размер ID игрока.

7. В строке 144 символов, от этих 144 вычитаем 68(получившиеся символы) получается 76, то есть, у нас еще для текста есть 76 символов.

8. У нас получается так:

static const fmt_str[] = "LeonYT сделал отличный урок, SCRIPTMAN сказал ему: %s, его ид: %d";
new string[sizeof(fmt_str)-2+76-2+3];
format(string, sizeof(string), fmt_str, params[0], playerid);
SCM(playerid, 0xFFFFFFFF, string);

Вот так считается текст.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
LeonYT

@SCRIPTMANДа, насчёт неудобства создания в одном участке кода несколько подсчётов строки с помощью второго способа я знаю.
Кстати насчёт твоего кода, раз уж речь пошла про добавление второго статика, то можно обойтись одной переменной строки (string). Просто нужно посчитать самую большую строку в начале, а потом через format её просто перезаписывать.

Пример:

static const fmt_str[] = "Ваш id: %d, ваш IP: %s, ваш Ник: %s";
new string[sizeof(fmt_str)+(-2+3)+(-2+16)+(-2+MAX_PLAYER_NAME)], ip[16], name[MAX_PLAYER_NAME];
GetPlayerIp(playerid, ip, sizeof(ip));
GetPlayerName(playerid, name, sizeof(name));
format(string, sizeof(string), fmt_str, playerid, ip, name);
SCM(playerid, 0xFFFFFFFF, string);
//размер строки 73 ячейки

//Допустим нам нужно сунуть в код ещё одну строку, для которой нам потребуется меньше ячеек для вывода
static const fmt_str2[] = "Ваш Ping: %d";
//Нам не требуется создавать ещё одну string, мы воспользуемся старой, перезаписав её содержимое
format(string, sizeof(string), fmt_str2, GetPlayerPing(playerid));
SCM(playerid, 0xFFFFFFFF, string);

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Web

 

 


 

Изначально, автор Daniel Cortez. Почему о нем не слова?

 

 

 


static использовать гораздо лучше, я использую его везде, но и у него есть минусы..

 

какие же у него минусы?)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
SCRIPTMAN

@Wеb,1. неудобно использовать 2 или более сразу. 2. для новичка по началу будет не понятно, как для меня. 3. Долго писать, но можно конечно скопировать. 

Ну я уже привык, так что для меня - норм.


@Wеb,А что говорить о нем? Он больше теоретик, он вообще с другого портала, да и самповский - не наш.

Написал учебник ProPawn, откуда можно и узнать про этот static, но написал конечно не один.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Rikka

> 2. для новичка по началу будет не понятно, как для меня.

 

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

 

Неудобно, не есть плохо. Это скорей вам додумать чтоб было удобно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Web

@SCRIPTMAN, что за чушь? Удобство и восприятие ровно такое же, как объявлять через new или var. Про удобство говоришь? Загляни в свои темы. Они не воспринимаемы для новичков, просто вырезка копипаста кода из мода. Причем не полностью. И это от модератора!

 

Ну да, зачем говорорить про Кортеза. Может потому что он автор? Ну оно и не удивительно, тут большинство пренебрежительно к авторским правам относиться. Пусть даже к формальным.

Изменено пользователем Wеb

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
MYSTERYMAN

@SCRIPTMAN, а как зависит язык программирвоания и применяемые в нём практики от платформы для которой он используется? Что касатеся оператора static, назначение у него ничем не отличается от ЯП, которые испытали влияние языка Си.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
LeonYT

 

 


Изначально, автор Daniel Cortez. Почему о нем не слова?

Стоило-бы посмотреть повнимательнее, эта строка даже красным выделена, а вы не заметили...

 


Способ второй (Автор: Daniel Cortez):

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Alim2603

Тема очень полезна для таких как я

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
SCRIPTMAN

@Rikka,Мне было непривычно по началу, я мог запутаться, но сейчас уже все топ! 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
Авторизация  

  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу

×

Важная информация

Мы разместили cookie-файлы на ваше устройство, чтобы помочь сделать этот сайт лучше. Вы можете изменить свои настройки cookie-файлов, или продолжить без изменения настроек.