PDA

Просмотр полной версии : [Вопрос] есть ли альтернатив для Convert



Unreal
20.12.2015, 13:21
Всем привет
В это коде возвращается строка, а как можно его избежать или как подругому использовать ?
Есть ли способы кроме ссылок и возврат. строки

stock Convert(number)
{
new hours = 0,mins = 0, secs = 0, string[32];
hours = floatround(number / 3600);
mins = floatround((number / 60) - (hours * 60));
secs = floatround(number - ((hours * 3600) + (mins * 60)));
if(hours > 0) format(string,sizeof string, "%dH:%02dM:%02dS", hours, mins, secs);
else format(string, sizeof string, "%d:%02d", mins, secs);
return string;
}


format(string,sizeof(string),"AFK %s",Convert(AFK[playerid][AFK_Time]-3));
SetPlayerChatBubble(playerid,string,COLOR_ORANGE,30.0,3000);

$continue$
20.12.2015, 14:00
ofс, можно.
К препроцессорам:


#if !defined isnull
#define isnull(%0) \
(strcmp(%0,"NULL",false) == 0)
#endif




/*! Конвертирует время для AFK
* \param [in] number − время (в секундах)
* \param [out] output − преобразованое значение
* \param [in] length − размер массива output
*/
stock ConvertTimeForAFK(number, output[], length = sizeof(output))
{
if(!isnull(output))
{
output[0] = '\0';
}
new string[18];
if(number > 3599) format(string, sizeof(string), "Íà ïàóçå %d:%02d:%02d", number / 3600, number % 3600/60, number % 3600 % 60);
else if(number > 59) format(string, sizeof(string), "Íà ïàóçå %d:%02d", number / 60, number % 60);
else format(string, sizeof(string), "Íà ïàóçå %d ñåê.", number);
strins(output, string, 0, length);
}



main()
{
new result[18];
ConvertTimeForAFK(6000, result);
print(result);
}



Вариант с 1 массивом:


main()
{
new result[18];
ConvertTimeForAFK(84000, result);
print(result);
}



stock ConvertTimeForAFK(number, output[], length = sizeof(output))
{
if(!isnull(output))
{
output[0] = '\0';
}
if(number > 3599) format(output, length, "На паузе %d:%02d:%02d", number / 3600, number % 3600/60, number % 3600 % 60);
else if(number > 59) format(output, length, "На паузе %d:%02d", number / 60, number % 60);
else format(output, length, "На паузе %d сек.", number);
}

http://i.imgur.com/wKziYxN.png

Unreal
20.12.2015, 15:36
ofс, можно.



/*! Конвертирует время для AFK
* \param [in] number − время (в секундах)
* \param [out] output − преобразованое значение
* \param [in] length − размер массива output
*/
stock ConvertTimeForAFK(number, output[] = "\0", length = sizeof(output))
{
new string[18];
if(number > 3599) format(string, sizeof(string), "На паузе %d:%02d:%02d", number / 3600, number % 3600/60, number % 3600 % 60);
else if(number > 59) format(string, sizeof(string), "На паузе %d:%02d", number / 60, number % 60);
else format(string, sizeof(string), "На паузе %d сек.", number);
strins(output, string, 0, length);
}



main()
{
new result[18];
ConvertTimeForAFK(6000, result);
print(result);
}

а можно ему что либо возвращать ?

$continue$
20.12.2015, 15:56
а можно ему что либо возвращать ?

Кому? Для какой цели?

L0ndl3m
20.12.2015, 16:20
а можно ему что либо возвращать ?
Насиловать стек? Пожалуйста. В pawn крайне не рекомендуется возвращать строки.
Используйте вариант, который вам был предложен от $continue, он более менее нормальный ( btw, можно было использовать 1 массив ).

$continue$
20.12.2015, 16:43
Насиловать стек? Пожалуйста. В pawn крайне не рекомендуется возвращать строки.
Используйте вариант, который вам был предложен от $continue, он более менее нормальный ( btw, можно было использовать 1 массив ).
Окей. Обновил пост.

L0ndl3m
20.12.2015, 16:49
Окей. Обновил пост.
Только сейчас заметил, почему 2 аргумент необязателен? Если его пропустить то можно словить краш сервера.

$continue$
20.12.2015, 17:05
Только сейчас заметил, почему 2 аргумент необязателен? Если его пропустить то можно словить краш сервера.
Бывает.
P.S: Fix.

L0ndl3m
20.12.2015, 17:48
Бывает.
P.S: Fix.
Теперь, если массив не пустой, то первая ячейка этого массива будет концом строки => снова краш.
Мне кажется тут без проверки будет лучше?

$continue$
20.12.2015, 18:37
Теперь, если массив не пустой, то первая ячейка этого массива будет концом строки => снова краш.
Мне кажется тут без проверки будет лучше?


http://i.imgur.com/OWL8nNW.png
http://i.imgur.com/eZK3okJ.png

К большому сожалению я не смог вызвать данный краш. CrashDetec молчит. Покажи как вызвать?

L0ndl3m
20.12.2015, 19:12
http://i.imgur.com/OWL8nNW.png
http://i.imgur.com/eZK3okJ.png

К большому сожалению я не смог вызвать данный краш. CrashDetec молчит. Покажи как вызвать?

А вот при тестировании на хостинге, у меня, к сожалению, происходит краш. Если windows как-то "игнорирует" такие дыры в коде, то на том же линуксе у тебя не пройдет такая операция.

Всё будет отлично, если убрать проверку где используется макрос "isnull".

Unreal
20.12.2015, 19:39
Насиловать стек? Пожалуйста. В pawn крайне не рекомендуется возвращать строки.


Я имел ввиду ( return true/false )

stock ConvertTimeForAFK(number, output[] = "\0", length = sizeof(output))
{
new string[18];
if(number > 3599) format(string, sizeof(string), "На паузе %d:%02d:%02d", number / 3600, number % 3600/60, number % 3600 % 60);
else if(number > 59) format(string, sizeof(string), "На паузе %d:%02d", number / 60, number % 60);
else format(string, sizeof(string), "На паузе %d сек.", number);
strins(output, string, 0, length);
return true;
}

L0ndl3m
20.12.2015, 21:23
Если возвращать данной функции число, то не вижу смысла в этом.

Desulaid
20.12.2015, 21:47
А не проще ли использовать в аргументах функции ссылки?


stock AFK_TimeConvetr(value, &hour, &minute, &second)
{
hour = floatround(value / 3600);
minute = floatround((value / 60) - (hour * 60));
second = floatround(value - ((hour * 3600) + (minute * 60)));
}

main()
{
new afk_time;

afk_time = 61;

new afk_time_h, afk_time_m, afk_time_s;

AFK_TimeConvetr(afk_time, afk_time_h, afk_time_m, afk_time_s);

if (afk_time_h > 0)
printf("Игрок на паузе уже %02i:%02i:%02i", afk_time_h, afk_time_m, afk_time_s);
else
printf("Игрок на паузе уже %02i:%02i", afk_time_m, afk_time_s);
}

VVWVV
21.12.2015, 03:27
У ТС принято записывать секунды полученные с таймера, а с вашим примером придётся вызывать функцию gettime (При использовании данной функций, потребность вашей функции пропадает, так как при использовании gettime мы можем получить время: в часах, в минутах, в секундах), после чего записывать в переменную, а после передавать их в функцию.
Также вместо макроса isnull мы можем определять размер аргумента output, например (альтернативный вариант):


stock
AnotherFunction(output[], size = sizeof output)
{
if (size == 1) print("-- null --");
else print("-- not null --");
return;
}

main()
{
AnotherFunction(""); // Result: -- null --
AnotherFunction("1"); // Result: -- not null --
}




А не проще ли использовать в аргументах функции ссылки?
Конечно можно, однако:

Есть ли способы кроме ссылок и возврат. строки


Идеальная функция получилась только у пользователя $continue$:




main()
{
new result[18];
ConvertTimeForAFK(84000, result);
print(result);
}



stock ConvertTimeForAFK(number, output[], length = sizeof(output))
{
if(!isnull(output))
{
output[0] = '\0';
}
if(number > 3599) format(output, length, "На паузе %d:%02d:%02d", number / 3600, number % 3600/60, number % 3600 % 60);
else if(number > 59) format(output, length, "На паузе %d:%02d", number / 60, number % 60);
else format(output, length, "На паузе %d сек.", number);
}