Замена подстроки в строке
#1

Не могу понять почему strins не работает второй раз после замены подстроки <ToPlanet>
и почему то print("End"); не выводится

Code:
new ToPlanet[20] = "Santa Marina Beach";

public OnGameModeInit()
{
	new string[] = "- Мое имя <Ranger>, я <ToPlanet> представляю <FromStar>, депортамента <ToPlanet> штата <ToStar>.\n";
	print( replaceString(string, "<ToPlanet>", ToPlanet) );
	return 1;
}
pawn Code:
stock replaceString(getStr[], const findstr[], const replacestr[])
{
    new start = strfind(getStr, findstr, true);
    do
    {
        new end = start + strlen(findstr);
        strdel(getStr, start, end);
        strins(getStr, replacestr, start, 1920);
        start = strfind(getStr, findstr, true, start+strlen(replacestr));
    } while(start != -1);
    print("End");
    return getStr;
}
Необходимо, создать ф-ию замены подстроки без использования format, т.к. она очень медленная.
Где getStr строка большой длины (примерно 1920, возможно и больше) для формирования текста в диалоговом окне.

Вот для чего мне это надо

Code:
enum locinfo
{
	locused,
	locmessage[128],
	loc
};
new LOCATION[15][locinfo] = {....};

new msgitem[1920];
for(new i=0; i<sizeof(LOCATION); i++)
{
	if(LOCATION[i][locused] == 1)
	{
		strcat(msgitem, LOCATION[i][locmessage]);
	}
}
msgitem = replaceString(msgitem, "<ToPlanet>", ToPlanet);
MenuOperation[playerid] = 301;
ShowPlayerDialog(playerid,47,DIALOG_STYLE_MSGBOX,"Администрации Штата",msgitem,"Согласиться","Отказаться");
Второй маленький вопрос. Можно не обращать внимание.
В strins последний параметр
//maxlength=sizeof replacestr - это Максимальный вставляемый размер подстроки replacestr
или
//maxlength=sizeof getStr - это Максимальный вставляемый размер строки getStr
и вообще зачем он нужен?
Reply
#2

код не стал разбирать,но может у тебя print("END"); не выводится из-за того что запускается бесконечный цикл?...проверь это
Reply
#3

Можно сделать

Code:
stock replaceString(getStr[], const findstr[], const replacestr[])
{
	new getStr[1920];
	strmid(getStr, str, 0, strlen(str));
...
и всё будет работать, по крайней мере на уровне консоли и одной строки текста,
т.е. вот так работает только на уровне консоли и одной строки текста, а в самом моде не пашет.
Code:
stock replaceString(str[], const findstr[], const replacestr[])
{
	new getStr[1920];
	strmid(getStr, str, 0, strlen(str));
	new start = strfind(getStr, findstr, true);
	while(start != -1)
	{
		new end = start + strlen(findstr);
		strdel(getStr, start, end);
		strins(getStr, replacestr, start, 1920);
		start = strfind(getStr, findstr, true, start+strlen(replacestr));
	}
	print("End");
	return getStr;
}
но тогда будет предопределена входящая строка размером getStr[1920];

А хотелось бы ф-ию написать, которая будет производить замену подстроки в строке любого размера, т.е. размера того, что пришло.
Reply
#4

зададимся другим вопросом: настолько ли медленная функция формат чтобы пренебрегать ей и писать собственную?
Reply
#5

Вопрос не о том.
Создай другую тему, для споров на эту тему. Я уже тестировал все ф-ии и видел на сколько один и тот же текст на 10000 цыклах даёт милисекунд.
Reply
#6

Quote:
Originally Posted by DANGER1979
View Post
В strins последний параметр
//maxlength=sizeof replacestr - это Максимальный вставляемый размер подстроки replacestr
или
//maxlength=sizeof getStr - это Максимальный вставляемый размер строки getStr
и вообще зачем он нужен?
лол, смотри определение функции (еще можно заглянуть в документацию по строковым функциям павна)
native bool: strins(string[], const substr[], pos, maxlength=sizeof string);
функция должна знать размер string, чтобы не выйти за ее пределы
внутри функции узнать размер переданного массива не возможно, поэтому его размер передается отдельным параметром. чтобы не утруждать прикладного программиста указывать каждый раз размер вручную этому параметру дают значение по умолчанию равное sizeof массив. (внутри функции sizeof работать не будет, а вот как подставляемый параметр при вызове сработает)
Тебе в своей функции нужно тоже создать дополнительный подставляемый параметр, равный размеру переданного массива, и когда вызываешь strins передавать этот размер явно.
Надеюсь на основе вышесказанного ты во всем разберешься и решишь остальные проблемы (как я понял вытекающие из этой).
End скорей всего не выводился из за ошибки вызванной указанием не верного размера массива (1920).
Reply
#7

Вот переделал с учётом того что ты сказал

Code:
new ToPlanet[20] = "Santa Marina Beach";

public OnGameModeInit()
{
	new string[] = "- Мое имя <Ranger>, я <ToPlanet> представляю <FromStar>, депортамента <ToPlanet> штата <ToStar>.\n";
	print( replaceString(string, sizeof(string), "<ToPlanet>", ToPlanet) );
	return 1;
}
pawn Code:
stock replaceString(getStr[], size, const findstr[], const replacestr[])
{
    new start = strfind(getStr, findstr, true);
    do
    {
        new end = start + strlen(findstr);
        strdel(getStr, start, end);
        strins(getStr, replacestr, start, size);
        start = strfind(getStr, findstr, true, start+strlen(replacestr));
    } while(start != -1);
    print("End");
    return getStr;
}
и всё равно ноль по фазе
Reply
#8

ты объявил размер string как кол-во символов этой строки
и хочешь вставить в эту строку ещё символов, сверх размера строки...
pawn Code:
#include <a_samp>
main()
{
    new ToPlanet[20] = "Santa Marina Beach";
    new string[256];
    string = "- Мое имя <Ranger>, я <ToPlanet> представляю <FromStar>, депортамента <ToPlanet> штата <ToStar>.\n";
    print( replaceString(string, sizeof(string), "<ToPlanet>", ToPlanet) );
}
stock replaceString(getStr[], size, const findstr[], const replacestr[])
{
    new start = strfind(getStr, findstr, true);
    while(start != -1) {
        new end = start + strlen(findstr);
        strdel(getStr, start, end);
        strins(getStr, replacestr, start, size);
        start = strfind(getStr, findstr, true, start+strlen(replacestr));
   }
    return getStr;
}
Reply
#9

Aleks10 большое спасибо. А я ни как не мог понять, что за ерунда, а про такое простое правило не подумал.
Ещё раз спасибо.

Кстати size тоже можно не ставить, а поставить strlen(getStr) или задать сразу 1920

Осталось проверить это уже на моде как будет выводится в диалоге
Reply
#10

Quote:
Originally Posted by DANGER1979
View Post
Кстати size тоже можно не ставить, а поставить strlen(getStr) или задать сразу 1920
strlen перебирает строку в поисках первого нуль-символа - чем определяет ее длину, а не размер.
задавать сразу большие значения не советую.
просто перенеси свой параметр size в конец списка параметров и дай ему значение по умолчанию через sizeof
stock replaceString(getStr[], const findstr[], const replacestr[], size = sizeof getStr)
и тогда при вызове не нужно будет ниче лишнего писать
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)