Формирование списка из порядковых номеров на основе атрибута
-
-
09.08.2021 #76657
Николай
КлючникGnusmas 09 авг 2021, 13:11Доброго времени суток. Заранее прошу прощения за название темы. Можете предложить более подходящее, и я сменю.
В качестве кода выступает С/С++, но не суть важно, свой вариант можете описать хоть словами.
Суть вопроса. Есть некая УЖЕ РЕАЛИЗОВАННЯ система, со своим файлом конфигурации формата XML.
В файле конфигурации системы есть список выходов:<,outs>,
<,i id=1 type=LED1>,
<,name>,Out_1<,/name>,
<,/i>,
<,i id=2 type=LED2>,
<,name>,Out_2<,/name>,
<,/i>,
<,i id=3 type=OUT>,
<,mode>,control<,/mode>,
<,name>,Out_3<,/name>,
<,/i>,
<,i id=4 type=SIR>,
<,name>,Out_4<,/name>,
<,/i>,
<,/outs>,Выходы могут иметь пропуски (например будут начинаться с LED2, и он в таком случае будет первым выходом в системе, и всего выходов станет 3 вместо 4), но меняться местами они не могут.
Выходы назначаются пользователям, но почему-то сделано это как-то странно, не по id, а по type.
То есть настройки пользователя выглядят следующим образом:<,users>,
<,i id=1>,
<,name>,User_1<,/name>,
<,outs>,LED1,OUT<,/outs>,
<,/i>,
<,i id=2>,
<,name>,User_2<,/name>,
<,outs>,LED2,SIR<,/outs>,
<,/i>,
<,/users>,Мне в своей системе на основании этих настроек необходимо сформировать строку выходов пользователя, которая будет содержать их id вместо type.
Так как это УЖЕ РЕАЛИЗОВАННЯ система, вносить изминения в формат XML уже не представляется возможным.
Все нужно сделать внутри моей программы, не затрагивая существующий файл конфигурации.
Для хранения настроек выходов я создал массив структур типа:
typedef struct {
char name[NAME_LEN_SIZE],
char type,
} outs_t,
Для хранения настроек пользователей я создал массив структур типа:
typedef struct {
char name[NAME_LEN_SIZE],
char outs[sizeof(1,2,3,4)],
} users_t,
В своем коде при считывании файла конфигурации и заполнении настроек выходов я беру последнюю букву type выхода, и назначаю его типом.
// read 1 last symbol of type: 1-LED1, 2-LED2, T-OUT, R-SIR
outs[id].type = readingString[readingString.indexOf(>,)-1],
И далее в коде делаю следующий финт:uint8_t i = 0,
char outsStringsizeofLED1,LED2,OUT,SIR,
for , i <, outsLen, ++i{
outsStringi = readingStringreadingString.indexOf<,outs>, + strlen<,outs>, + i,
}
outsStringi = ,
i = 0,
uint8_t j = 0,
if strstroutsString,LED1 != NULL{
usersid.outsj++ = 1,
usersid.outsj++ = ,,
}
if strstroutsString,LED2 != NULL{
while outsi.type != 2{
i++,
}
usersid.outsj++ = i+1,
usersid.outsj++ = ,,
}
if strstroutsString,OUT != NULL{
while outsi.type != T{
i++,
}
usersid.outsj++ = i+1,
usersid.outsj++ = ,,
}
if strstroutsString,SIR != NULL{
while outsi.type != R{
i++,
}
usersid.outsj++ = i+1,
usersid.outsj++ = ,,
}
// delete last ,
usersid.outs–j = ,И получаю заветный список выходов пользователя:
1,3 – для User_1
2,4 – для User_2
Все работает, но может быть вы видите более красивый вариант ?_pv 09 авг 2021, 17:32std::map<,std::string, int>, outs {{LED1, 1}, {LED2, 2}, {OUT, 3}, {SIR, 4}},
std::multimap<,std::string, std::string>, users {{user_1, LED1}, {user_1, OUT}, {user_2, LED2}, {user_2, SIR}},
auto r = users.equal_range(user_1),
for (auto it = r.first, it != r.second, it++) printf(%d,, outsit->,second),Gnusmas 09 авг 2021, 22:50_pv писал(а):std::map<,std::string, int>, …Благодарю. Я в плюсах до этого разве что ипользовал базовый фунционал ардуинолиб, так что это непросто, постараюсь разобраться, но код рабочий проверил.
Пока замечен только 1 большой минус: даже без строчки Вашего кода, подключение #include <,iostream>, и #include <,map>, (необходимых для успешной компиляции подобного кода) уже дают:
RAM: [===== ] 53.8% (used 44064 bytes from 81920 bytes)
Flash: [===== ] 48.5% (used 506553 bytes from 1044464 bytes)
Против того что было до их подключения:
RAM: [==== ] 39.9% (used 32704 bytes from 81920 bytes)
Flash: [=== ] 30.7% (used 321141 bytes from 1044464 bytes)
Я в замешательстве. Может пока оставлю как было, мне ведь еще кучу функционала реализовывать, может быть в конце поиграюсь, если место останеться.
Контроллер, если что – ESP8266, среда разработки – плагин PlatformIO под VS Code, компилятор – GCC/Arduino.Minoru 10 авг 2021, 12:45Gnusmas писал(а):Благодарю. Я в плюсах до этого разве что использовал базовый фунционал ардуинолиб, так что это непросто, постараюсь разобраться, но код рабочий проверил.
Пока замечен только 1 большой минус: даже без строчки Вашего кода, подключение #include <,iostream>, и #include <,map>, (необходимых для успешной компиляции подобного кода) уже дают:
RAM: [===== ] 53.8% (used 44064 bytes from 81920 bytes)
Flash: [===== ] 48.5% (used 506553 bytes from 1044464 bytes)
Против того что было до их подключения:
RAM: [==== ] 39.9% (used 32704 bytes from 81920 bytes)
Flash: [=== ] 30.7% (used 321141 bytes from 1044464 bytes)
Я в замешательствеЯ бы попробовал еще потрясти дерево вызовов: stackoverflow.com/questions/668 … gcc-and-ld
-
- Вы должны войти в систему, чтобы ответить в этой теме.