Intruder
IntruderAug. 20, 2019, 5:04 p.m.

При обращении к QMap и записи в файл, меняется последовательность выводимой информации

Добрый день, уважаемые Гуру!

Вопрос может и странный, но все таки.
Создаю и добавляю значения

QMap<QString, QString> *map = new QMap<Qstring, QString>();
map->insert("key1", "value1");
map->insert("key2", "value2");
map->insert("key3", "value3");

После читаю данные из словаря и записываю в файл

QMap<Qstring, QString>::iterator it = map->begin();
for(;it != map->end(); ++it)
{
    if(it.key() == "key1")
    {
        добавили значение в файл;
    }
    if(it.key() == "key2")
    {
        добавили значение в файл;
    }
    if(it.key() == "key3")
    {
        добавили значение в файл;
    }
}

Так вот, при записи одной и той же последовательности также обновляется файл, так как меняется выходная последовательность.
Что я сделал неправильно?

We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.

Do you like it? Share on social networks!

15
R
  • Aug. 20, 2019, 5:15 p.m.
  • (edited)

добрий день, так а що вам заважає зробити по документації? ніколи таких пробелм не виникало

  QMap<QString, int> map;
  QMapIterator<QString, int> i(map);
  while (i.hasNext()) {
      i.next();
      cout << i.key() << ": " << i.value() << endl;
  }

Here's the same code, but using an STL-style iterator this time:

  QMap<QString, int>::const_iterator i = map.constBegin();
  while (i != map.constEnd()) {
      cout << i.key() << ": " << i.value() << endl;
      ++i;
  }

і можна без new

QMap<QString, QString> map;

    Используешь не тот контейнер. Если хочешь получить последовательный вывод как и добавлял - используй QList. а вообще смотря для каких целей ты все это юзайешь.

      Intruder
      • Aug. 20, 2019, 5:47 p.m.

      Мне нужно чтобы было однозначное соответсвие ключ-значение. Разве QList это позволяет? Если да, то как это реализовать?

        Evgenii Legotckoi
        • Aug. 20, 2019, 6:25 p.m.

        вы можете испльзовать QList, просто помещайте туда QPair, будет примерно тоже самое. Просто QMap автоматически сортируется по ключу.

        QList<QPair<QString, QString>> list_with_pair;
        list_with_pair.push_back(QPair("key1", "value1"));
        
          Александр Панюшкин
          • Aug. 20, 2019, 11:37 p.m.
          • (edited)
          • The answer was marked as a solution.

          Добрый день.
          Я бы хотел добавить, что в вашем коде можно было бы использовать слово auto и цикл for с перебором. Так код получился бы компактнее:

          auto map = new QMap<Qstring, QString>();
          map->insert("key1", "value1");
          map->insert("key2", "value2");
          map->insert("key3", "value3");
          
          for (const auto& it : map)
          {
              if(it.key() == "key1")
              {
                  добавили значение в файл;
              }
              if(it.key() == "key2")
              {
                  добавили значение в файл;
              }
              if(it.key() == "key3")
              {
                  добавили значение в файл;
              }
          }
          

          Но не очень ясен вообще смысл подобного перебора, т.к. вы и так можете проверять наличие ключа:

          if (map->contains("key1")) {
              Do something;
            }
          

          и т.д.

          И, как уже сказали ранее, QMap не гарантирует сохранения порядка элементов. Воспользуйтесь другим контейнером, например, как предложил Евгений. Правда, в таком случае вы потеряете возможность обращения по ключу, а также будет возможно возникновение ошибки из-за дублирования ключей.

            Александр, добрый день.

            Проверка нужна мне для случая, когда в словаре может не оказаться среди ключей того, что мне нужно. А так да, я с Вами полностью согласен. То что предложил Евгений, мне очень понравилось, но это усложняет код. Мне со словарем нравится больше.

            Спасибо Вам за помощь.

              Evgenii Legotckoi
              • Aug. 21, 2019, 4:21 p.m.
              • (edited)

              Вообще, это можно переписать так

              auto map = new QMap<Qstring, QString>();
              map->insert("key1", "value1");
              map->insert("key2", "value2");
              map->insert("key3", "value3");
              
              for (const auto& [key, value] : map)
              {
                  if(key == "key1")
                  {
                      // добавили значение в файл;
                  }
                  if(key == "key2")
                  {
                      // добавили значение в файл;
                  }
                  if(key == "key3")
                  {
                      // добавили значение в файл;
                  }
              }
              

              Не помню только, какой это стандарт, C++14 или C++17

                Intruder
                • Aug. 21, 2019, 6:10 p.m.

                Евгений, данная конструкция не работает

                for (const auto& [key, value] : map)
                {
                    if(key == "key1")
                    {
                        // добавили значение в файл;
                    }
                    if(key == "key2")
                    {
                        // добавили значение в файл;
                    }
                    if(key == "key3")
                    {
                        // добавили значение в файл;
                    }
                }
                

                Я переписал цикл следующим образом, потому что проверка в этом случае не нужна. Мне просто нужно было просто создать атрибуты xml тега. И поэтому в словаре будет лежать только то, что я туда положу.
                Но все равно порядок атрибутов внутри тега меняется каждый раз, хотя последовательность одна и та же и в словарь кладется каждый раз в одинаковом порядке.
                А сам цикл я переписал вот так:

                auto *map = object.getMap();
                QMap<QString, QString>::iterator it = map->begin();
                for(;it != map->end(); ++it)
                {
                    domElement.setAttribute(it.key(), it.value());
                }
                

                Но вот почему каждый раз последовательность берется по-разному не понимаю. Единственное предположение - так работает итератор. Можно конечно пойти по пути QList > map... Попробую.

                  Evgenii Legotckoi
                  • Aug. 21, 2019, 6:13 p.m.
                  • (edited)

                  Евгений, данная конструкция не работает

                  Данная конструкция работает, но работает при использовании стандарта C++17. Чтобы его включить, необходимо прописать в pro файле следующее

                  CONFIG += c++17
                  QMAKE_CXXFLAGS += /std:c++17
                  

                  Но вот почему каждый раз последовательность берется по-разному не понимаю. Единственное предположение - так работает итератор.

                  Дело не в работе итератора, а в том, что QMap автоматически сортируется. Я об этом уже говорил выше.
                  Если вы постоянно что-то добавляете или удаляете, то естественно, что последовательность элементов может изменяться.

                    Intruder
                    • Aug. 21, 2019, 6:23 p.m.

                    Если вы постоянно что-то добавляете или удаляете, то естественно, что последовательность элементов может изменяться.

                    Даже если добавляется одно и тоже количество пар "ключ-значение"? Ну если так, то тогда чуть позже перепишу на конструкцию QList.

                        CONFIG += c++17
                        QMAKE_CXXFLAGS += /std:c++17
                    

                    Если я это напишу, то мне придется весь код писать на новом стандарте или использовать можно будет и старые конструкции?

                      Intruder
                      • Aug. 21, 2019, 6:24 p.m.

                      Евгений,

                      Если вы постоянно что-то добавляете или удаляете, то естественно, что последовательность элементов может изменяться.

                      Даже если добавляется одно и тоже количество пар "ключ-значение"? Ну если так, то тогда чуть позже перепишу на конструкцию QList.

                          CONFIG += c++17
                          QMAKE_CXXFLAGS += /std:c++17
                      

                      Если я это напишу, то мне придется весь код писать на новом стандарте или использовать можно будет и старые конструкции?

                        Evgenii Legotckoi
                        • Aug. 21, 2019, 6:26 p.m.

                        Если я это напишу, то мне придется весь код писать на новом стандарте или использовать можно будет и старые конструкции?

                        Вам ничего не придётся переписывать, просто получите возможность использовать новый стандарт. Единственные проблемы могут возникать, если вы пишите библиотеку, которую используют другие проекты, которые работают только со старыми стандартами, но это видимо не ваш случай на данный момент.

                          Intruder
                          • Aug. 21, 2019, 6:29 p.m.

                          Спасибо за помощь, Евгений.

                            и всё равно не понимаю, зачем перебирать всю мапу? можно просто проверять наличие ключа и при его наличии (или отсутствии) делать какие-то действия.
                            у вас получается избыточный код.

                              Александр, мне не нужно перебирать. Вы говорите правильно, сначала я написал избыточный код просто не подумав. Задача такая, мне нужно просто переложить из QMap в атрибуты xml тега все, что там лежит. И еще раз повторюсь, изначально я решил задачу в лоб не более того. Вот при перекладывании последовательность атрибутов всегда меняется при неизменности словаря. Поэтому я и спросил почему так, может быть я что-то делаю неправильно.

                                Comments

                                Only authorized users can post comments.
                                Please, Log in or Sign up
                                Ua

                                Qt - Test 001. Signals and slots

                                • Result:84points,
                                • Rating points4
                                Ua

                                Qt - Test 001. Signals and slots

                                • Result:42points,
                                • Rating points-8
                                ОК

                                Qt - Test 001. Signals and slots

                                • Result:47points,
                                • Rating points-6
                                Last comments
                                ИМ
                                Игорь МаксимовNov. 22, 2024, 9:51 p.m.
                                Django - Tutorial 017. Customize the login page to Django Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
                                Evgenii Legotckoi
                                Evgenii LegotckoiOct. 31, 2024, 11:37 p.m.
                                Django - Lesson 064. How to write a Python Markdown extension Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
                                A
                                ALO1ZEOct. 19, 2024, 5:19 p.m.
                                Fb3 file reader on Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
                                ИМ
                                Игорь МаксимовOct. 5, 2024, 4:51 p.m.
                                Django - Lesson 064. How to write a Python Markdown extension Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
                                d
                                dblas5July 5, 2024, 8:02 p.m.
                                QML - Lesson 016. SQLite database and the working with it in QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
                                Now discuss on the forum
                                f
                                firstlunoxodFeb. 15, 2025, 1:46 p.m.
                                Рисование на QGraphicsScene при зажатой кнопке мыши Подскажите, пожалуйста! Как данный класс можно дополнить, чтобы созданные объекты можно было перемещать мышкой по сцене?
                                Дмитрий
                                ДмитрийFeb. 3, 2025, 4:24 p.m.
                                Создание deb-пакета. Как создать ярлык на рабочем столе после установки собственного deb-пакета? Всем привет. Сделал свой deb-пакет с программой. Всё устанавливается и работает. Ставлю по пути /usr/bin/my_application. Как для пользователя при установке пакета сразу создать ярлык на раб…
                                NW
                                Nayo WaiJan. 30, 2025, 7:22 p.m.
                                не запускается компьютер!!! Не запускается компьютер (точнее работает блок , но сам монитор вообще жесть)В общем я ничего с интернета не скачивала в последнее время. На компе никаких левых пр…
                                n
                                nklyJan. 3, 2025, 12:52 p.m.
                                Нужно запретить перемещение только некоторых итемов, остальные перемещать можно. Вопрос решен. Узнать QModelIndex элемента на который мы перетаскиваем другой элемент, можно с помощью функции indexAt(event->position().toPoint()) представления QTreeViev вызываемой в переопр…
                                M
                                MarselAug. 17, 2023, 12:26 a.m.
                                OAuth2.0 через VK, получение email Спасибо большое за помощь и простите за то что отнял время своей невнимательностью.

                                Follow us in social networks