Просмотр полной версии : [Вопрос] Парсинг строк pawn
Sersoftin
28.10.2014, 18:27
Есть строка:
new test[20] = "2014-10-28 00:40:00"; (например)
Есть переменные:
new year, month, day, hour, minut, second; (например)
Необходимо распарсить строку и забить в эти переменные нужные данные.
year = 2014;
month = 10;
day = 28;
hour = 0;
minut = 40;
second = 0;
sscanf отпадает, насколько я понял. Какие есть ещё не геморные способы, дабы не писать это все дело вручную? Может есть что-то.
Примерно так:
Функция:
stock ParseString(const str[], dest[][], const maxlength = sizeof(dest[]))
{
new
pos,
count,
offset;
do
{
switch(str[pos])
{
case '-', ' ', ':':
{
strmid(dest[count++], str, offset, pos, maxlength);
offset = pos + 1;
}
}
}
while(str[++pos] != EOS);
if(str[pos] == 0)
strmid(dest[count], str, offset, pos, maxlength);
}
Использование:
main()
{
new
test_string[20] = "2014-10-28 00:40:00";
new
parse_str[6][5],
year,
month,
day,
hour,
minute
second;
ParseString(test_string, parse_str);
year = strval(parse_str[0]);
month = strval(parse_str[1]);
day = strval(parse_str[2]);
hour = strval(parse_str[3]);
minute = strval(parse_str[4]);
second = strval(parse_str[5]);
}
Хотя вряд ли проще чем sscanf.
Sersoftin
28.10.2014, 23:05
Примерно так:
Функция:
stock ParseString(const str[], dest[][], const maxlength = sizeof(dest[]))
{
new
pos,
count,
offset;
do
{
switch(str[pos])
{
case '-', ' ', ':':
{
strmid(dest[count++], str, offset, pos, maxlength);
offset = pos + 1;
}
}
}
while(str[++pos] != EOS);
if(str[pos] == 0)
strmid(dest[count], str, offset, pos, maxlength);
}
Использование:
main()
{
new
test_string[20] = "2014-10-28 00:40:00";
new
parse_str[6][5],
year,
month,
day,
hour,
minute
second;
ParseString(test_string, parse_str);
year = strval(parse_str[0]);
month = strval(parse_str[1]);
day = strval(parse_str[2]);
hour = strval(parse_str[3]);
minute = strval(parse_str[4]);
second = strval(parse_str[5]);
}
Хотя вряд ли проще чем sscanf.
sscanf отрабатывает на строках, где данные разделяются пробелами. Загуглить, как распарсить подобное им я так и не смог. Не нашел инфы.
- - - Добавлено - - -
Думал насчет регулярок, плагин есть по ним. Но там все функции аля составить предкомпилированое регулярное выражение и по нему просто проверить строку, соответствует ли она ему (IsEmailValid, IsPasswordValid). А вытянуть данные по группам или ещё как-то нельзя (вроде :D). В том же C# или java это возможно.
sscanf отрабатывает на строках, где данные разделяются пробелами. Загуглить, как распарсить подобное им я так и не смог. Не нашел инфы.
В sscanf можно установить любой разделитель. Например:
sscanf("6+6+11", "p<+>iii", int1, int2, int3);
Разделителем станет знак сложения. В третьей версии sscanf Y-Less обещал поддержку нескольких разделителей сразу, но пока так и не сделал эту самую версию.
Но ты можешь просто записывать в БД/файл данные в виде, который будет удобночитаем машине. Например, в аккаунте игрока дата будет хранится так:
"2014-10-28 00:40:00"
А уже при записи форматируй её в
2014|10|28|00|40|00
и тогда проблем никаких с конвертированием не будет (а со временем и сам привыкнешь читать данные в таком формате).
Если же речь не о БД идёт, то делай всё наоборот: храни все данные изначально в виде отдельных переменных и уже при надобности их конвертируй в строку.
А вообще тебе изначально стоило озвучить конечную цель (в какой системе это использоваться будет). Может всё гораздо проще
Например, вот способ с использованием sscanf
new test_string[20] = "2014-10-28 00:40:00";
new pos = strfind(test_string, " ", false);
new result[2][11];
strmid(result[0], test_string, 0, pos);
strmid(result[1], test_string, pos+1, strlen(test_string));
new year, month, day, hour, minut, second;
sscanf(result[0], "p<->iii", year, month, day);
sscanf(result[1], "p<:>iii", hour, minut, second);
В виде функции подобное реализовать можно, но не думаю, что оно будет удачнее варианта Londlem
Sersoftin
29.10.2014, 02:12
Система бананов. Если дата разбана больше текущей - юзер в бане. Т.е. все сводится к сравнению даты и времени.
- - - Добавлено - - -
Я вообще изначально спросил: есть ли какие стандартные средства или что-нибудь такое, что не потребует от меня лишних телодвижений и мозговой активности, а вы мне уже готовые функции :) Так не интересно... :) Ну, спасибо, сейчас посмотрим :)
- - - Добавлено - - -
Наверное это будет лучшим выходом. Хранить в типе VARCHAR "2014|10|28|00|40|00" вот такое вот. Разницы не будет, я думаю. И на php взаимодействовать, если что тоже будет нормально. Спасибо всем :)
Попробуй для бана использовать UnixTime
Sersoftin
29.10.2014, 03:05
Попробуй для бана использовать UnixTime
Да время я по-другому получаю текущее + дату.
Система бананов. Если дата разбана больше текущей - юзер в бане. Т.е. все сводится к сравнению даты и времени.
Как уже и сказали выше, используй UnixTime. Его в любой момент с лёгкостью можно будет перевести в любой формат. И при сравнении проблем не будет
Sersoftin
29.10.2014, 13:40
Как уже и сказали выше, используй UnixTime. Его в любой момент с лёгкостью можно будет перевести в любой формат. И при сравнении проблем не будет
Не кайф к большим числам приближаться... При сравнении и так вроде проблем нет. Хотя памяти он займет поменьше наверное...
не кайф к большим числам приближаться...
Для паролей больше ячеек используется, нежели для будет использовано для хранения времени в формате секунд (сейчас всего 10 ячеек нужно). Да даже для текущей даты, что вы показали в примере, используется гораздо больше ячеек.
Да и в MySQL есть достаточно возможностей для работы с Unix Time (конвертация unixtime в дату/дату в unixtime т.п. Только разобраться нужно).
Это будет всяко лучше, чем конвертировать каждый раз дату и для хранения по 10 переменных создавать.
new date[20] = "2014-10-28 00:40:00";
new year, month, day, hour, minute, second;
sscanf(date, "P<-:>iiiiii", year, month, day, hour, minute,second);
Powered by vBulletin® Version 4.2.0 Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot