Перейти к содержанию
Авторизация  
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-файлов, или продолжить без изменения настроек.