PDA

Просмотр полной версии : [Function] auto_new_line - авто переход на новую строку.



Seviel
28.03.2019, 17:36
Название:
auto_new_line

Описание:
Проставляет \n по возможности на ближайшем пробеле.

Аргументы:

string - Массив со строкой в которой будет проставляться переходы
lenght_line - Количество символов в одной строке, по умолчанию 70
string_size - Размер строки, по умолчанию количество равно sizeof string



Код:



stock auto_new_line(string[], const lenght_line = 70, const string_size = sizeof string)
{
new
point = 0,
len = strlen(string),
check = 0;

while(point < len - lenght_line)
{
for(new j = point; j < point + lenght_line; ++j)
{
if(string[j] == '\n')
{
check = 1;
point = j + 1;
break;
}
}
if(check == 0)
{
for(new j = point + lenght_line; j >= 0; --j)
{
if(string[j] == ' ')
{
string[j] = '\n';
check = 1;
point = j;
break;
}
}
}
if(check == 0)
{
strins(string, "\n", point + lenght_line, string_size);
point = point + lenght_line + 1;
}
check = 0;
}
return 1;
}



Пример:



public OnPlayerSpawn(playerid)
{
new string[450] = "\
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod \
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, \
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. \
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu \
fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in \
culpa qui officia deserunt mollit anim id est laborum.\
";
auto_new_line(string, 70);
ShowPlayerDialog(playerid, 0, DIALOG_STYLE_MSGBOX, "Lorem ipsum", string, "Ok", "");
return 0;
}



https://pasteboard.co/I7vZkLz.png
https://pasteboard.co/I7vZkLz.png


Автор: knox

DeimoS
29.03.2019, 05:41
И название странное (функции обычно в CamelCase оформляют), и к реализации имеются вопросы.
Как минимум: и инициализация переменных внутри цикла, и вычисления в условии цикла, которые спокойно можно вынести за его пределы, дабы не проводить одну и ту же операцию каждый тик минорных циклов.

UPD: Так же, судя по коду, вот в таком случае:

new string[] = "test\ntest";
auto_new_line(string, 4);
Будет добавлен дополнительный перенос.

Seviel
29.03.2019, 10:55
И название странное (функции обычно в CamelCase оформляют).

Название специально не по стилю выбрал, дабы сразу было ясно что не стандартно(Мне лично так удобнее понимать когда самописная, а когда стандартная).


UPD: Так же, судя по коду, вот в таком случае:

new string[] = "test\ntest";
auto_new_line(string, 4);
Будет добавлен дополнительный перенос.
Не будет, этим занимается 1 for.


Как минимум: и инициализация переменных внутри цикла, и вычисления в условии цикла, которые спокойно можно вынести за его пределы, дабы не проводить одну и ту же операцию каждый тик минорных циклов.
Я не смог придумать более оптимального варианта это сделать.

DeimoS
29.03.2019, 11:55
Название специально не по стилю выбрал, дабы сразу было ясно что не стандартно(Мне лично так удобнее понимать когда самописная, а когда стандартная).

Ну всё же все остальные самописаные функции именуют именно в стиле CamelCase, о чём можешь найти многочисленные подтверждения в библиотеках/на форумах. И публиковать свою функцию, отходя от общепринятых "норм" - странновато. Особенно с учётом того, что стиль, который используешь ты, обычно используют для наименования переменных, что лишь создаст путаницу.



Не будет, этим занимается 1 for.
Хмм, ну вот даже тебе скрин с тестом, раз самому лень проверять было.
https://i.imgur.com/tUtz3uq.png
Но это даже по коду видно, ибо когда ты ищешь "\n", ты не учитываешь, что символ переноса может стоять следующим после того количества символов, которые нужно отделять. Отсюда и два переноса вместо одного.



Я не смог придумать более оптимального варианта это сделать.

Ну так говорю же, убрать инициализацию переменных из циклов + значение "point + lenght_line" высчитывать при каждой итерации while (создать переменную, записать значение в неё и уже использовать переменную в циклах), а не каждую итерацию минорных циклов.

- - - Добавлено - - -

Как-то так:
stock auto_new_line(string[], const max_line_size = 70, const string_size = sizeof string)
{
new
pos = 0,
j,
len = strlen(string),
l = len - max_line_size,
size_limit;

while(pos < l)
{
size_limit = pos + max_line_size + 1;

for(j = pos; j < size_limit; ++j)
{
if(string[j] == '\n')
{
pos = j + 1;
goto __skip;
}
}
size_limit -= 1;
for(j = size_limit; j > -1; --j)
{
if(string[j] == ' ')
{
string[j] = '\n';
pos = j;
goto __skip;
}
}

strins(string, "\n", size_limit, string_size);
pos = size_limit + 1;
__skip:
}
return 1;
}
И то это, вероятно, не всё, что можно тут сделать.