Формирование списка из порядковых номеров на основе атрибута

    • #76657
      Николай
      Ключник

      Gnusmas

      09 авг 2021, 13:11

      Доброго времени суток. Заранее прошу прощения за название темы. Можете предложить более подходящее, и я сменю.
      В качестве кода выступает С/С++, но не суть важно, свой вариант можете описать хоть словами.
      Суть вопроса. Есть некая УЖЕ РЕАЛИЗОВАННЯ система, со своим файлом конфигурации формата XML.
      В файле конфигурации системы есть список выходов:

      &lt,outs&gt,
      &lt,i id=1 type=LED1&gt,
      &lt,name&gt,Out_1&lt,/name&gt,
      &lt,/i&gt,
      &lt,i id=2 type=LED2&gt,
      &lt,name&gt,Out_2&lt,/name&gt,
      &lt,/i&gt,
      &lt,i id=3 type=OUT&gt,
      &lt,mode&gt,control&lt,/mode&gt,
      &lt,name&gt,Out_3&lt,/name&gt,
      &lt,/i&gt,
      &lt,i id=4 type=SIR&gt,
      &lt,name&gt,Out_4&lt,/name&gt,
      &lt,/i&gt,
      &lt,/outs&gt,

      Выходы могут иметь пропуски (например будут начинаться с LED2, и он в таком случае будет первым выходом в системе, и всего выходов станет 3 вместо 4), но меняться местами они не могут.
      Выходы назначаются пользователям, но почему-то сделано это как-то странно, не по id, а по type.
      То есть настройки пользователя выглядят следующим образом:

      &lt,users&gt,
      &lt,i id=1&gt,
      &lt,name&gt,User_1&lt,/name&gt,
      &lt,outs&gt,LED1,OUT&lt,/outs&gt,
      &lt,/i&gt,
      &lt,i id=2&gt,
      &lt,name&gt,User_2&lt,/name&gt,
      &lt,outs&gt,LED2,SIR&lt,/outs&gt,
      &lt,/i&gt,
      &lt,/users&gt,

      Мне в своей системе на основании этих настроек необходимо сформировать строку выходов пользователя, которая будет содержать их 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(&gt,)-1],
      И далее в коде делаю следующий финт:

      uint8_t i = 0,
      char outsStringsizeofLED1,LED2,OUT,SIR,
      for , i &lt, outsLen, ++i{
      outsStringi = readingStringreadingString.indexOf&lt,outs&gt, + strlen&lt,outs&gt, + 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:32
      std::map&lt,std::string, int&gt, outs {{LED1, 1}, {LED2, 2}, {OUT, 3}, {SIR, 4}},
      std::multimap&lt,std::string, std::string&gt, 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-&gt,second),

       

      Gnusmas

      09 авг 2021, 22:50
      _pv писал(а):
      std::map&lt,std::string, int&gt, …

      Благодарю. Я в плюсах до этого разве что ипользовал базовый фунционал ардуинолиб, так что это непросто, постараюсь разобраться, но код рабочий проверил.
      Пока замечен только 1 большой минус: даже без строчки Вашего кода, подключение #include &lt,iostream&gt, и #include &lt,map&gt, (необходимых для успешной компиляции подобного кода) уже дают:
      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:45
      Gnusmas писал(а):
      Благодарю. Я в плюсах до этого разве что использовал базовый фунционал ардуинолиб, так что это непросто, постараюсь разобраться, но код рабочий проверил.
      Пока замечен только 1 большой минус: даже без строчки Вашего кода, подключение #include &lt,iostream&gt, и #include &lt,map&gt, (необходимых для успешной компиляции подобного кода) уже дают:
      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

Viewing 0 reply threads
  • Вы должны войти в систему, чтобы ответить в этой теме.
Интepecнoe нa фopумe:
Авторизация
*
*
Регистрация
*
*
*
Генерация пароля
×