Intruder
Intruder20 августа 2019 г. 7:04

При обращении к 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")
    {
        добавили значение в файл;
    }
}

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

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Вам это нравится? Поделитесь в социальных сетях!

15
R
  • 20 августа 2019 г. 7:15
  • (ред.)

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

  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;
    ВЖ
    • 20 августа 2019 г. 7:17

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

      Intruder
      • 20 августа 2019 г. 7:47

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

        Evgenii Legotckoi
        • 20 августа 2019 г. 8:25

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

        QList<QPair<QString, QString>> list_with_pair;
        list_with_pair.push_back(QPair("key1", "value1"));
        
          Александр Панюшкин
          • 20 августа 2019 г. 13:37
          • (ред.)
          • Ответ был помечен как решение.

          Добрый день.
          Я бы хотел добавить, что в вашем коде можно было бы использовать слово 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 не гарантирует сохранения порядка элементов. Воспользуйтесь другим контейнером, например, как предложил Евгений. Правда, в таком случае вы потеряете возможность обращения по ключу, а также будет возможно возникновение ошибки из-за дублирования ключей.

            Intruder
            • 21 августа 2019 г. 6:16

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

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

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

              Evgenii Legotckoi
              • 21 августа 2019 г. 6:21
              • (ред.)

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

              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
                • 21 августа 2019 г. 8:10

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

                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
                  • 21 августа 2019 г. 8:13
                  • (ред.)

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

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

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

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

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

                    Intruder
                    • 21 августа 2019 г. 8:23

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

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

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

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

                      Intruder
                      • 21 августа 2019 г. 8:24

                      Евгений,

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

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

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

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

                        Evgenii Legotckoi
                        • 21 августа 2019 г. 8:26

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

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

                          Intruder
                          • 21 августа 2019 г. 8:29

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

                            Александр Панюшкин
                            • 21 августа 2019 г. 8:30

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

                              Intruder
                              • 21 августа 2019 г. 8:36

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

                                Комментарии

                                Только авторизованные пользователи могут публиковать комментарии.
                                Пожалуйста, авторизуйтесь или зарегистрируйтесь
                                e
                                • ehot
                                • 31 марта 2024 г. 14:29

                                C++ - Тест 003. Условия и циклы

                                • Результат:78баллов,
                                • Очки рейтинга2
                                B

                                C++ - Тест 002. Константы

                                • Результат:16баллов,
                                • Очки рейтинга-10
                                B

                                C++ - Тест 001. Первая программа и типы данных

                                • Результат:46баллов,
                                • Очки рейтинга-6
                                Последние комментарии
                                k
                                kmssr8 февраля 2024 г. 18:43
                                Qt Linux - Урок 001. Автозапуск Qt приложения под Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
                                АК
                                Анатолий Кононенко5 февраля 2024 г. 1:50
                                Qt WinAPI - Урок 007. Работаем с ICMP Ping в Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
                                EVA
                                EVA25 декабря 2023 г. 10:30
                                Boost - статическая линковка в CMake проекте под Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
                                J
                                JonnyJo25 декабря 2023 г. 8:38
                                Boost - статическая линковка в CMake проекте под Windows Сделал всё по-как у вас, но выдаёт ошибку [build] LINK : fatal error LNK1104: не удается открыть файл "libboost_locale-vc142-mt-gd-x64-1_74.lib" Хоть убей, не могу понять в чём дел…
                                G
                                Gvozdik18 декабря 2023 г. 21:01
                                Qt/C++ - Урок 056. Подключение библиотеки Boost в Qt для компиляторов MinGW и MSVC Для решения твой проблемы добавь в файл .pro строчку "LIBS += -lws2_32" она решит проблему , лично мне помогло.
                                Сейчас обсуждают на форуме
                                a
                                a_vlasov14 апреля 2024 г. 6:41
                                Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Евгений, добрый день! Такой вопрос. Верно ли следующее утверждение: Любое Android-приложение, написанное на Java/Kotlin чисто теоретически (пусть и с большими трудностями) можно написать и на C+…
                                Павел Дорофеев
                                Павел Дорофеев14 апреля 2024 г. 2:35
                                QTableWidget с 2 заголовками Вот тут есть кастомный QTableView с многорядностью проект поддерживается, обращайтесь
                                f
                                fastrex4 апреля 2024 г. 4:47
                                Вернуть старое поведение QComboBox, не менять индекс при resetModel Добрый день! У нас много проектов в которых используется QComboBox, в версии 5.5.1, когда модель испускает сигнал resetModel, currentIndex не менялся. В версии 5.15 при resetModel происходит try…
                                P
                                Pisych27 февраля 2023 г. 4:04
                                Как получить в массив значения из связанной модели? Спасибо, разобрался:))
                                AC
                                Alexandru Codreanu19 января 2024 г. 11:57
                                QML Обнулить значения SpinBox Доброго времени суток, не могу разобраться с обнулением значение SpinBox находящего в делегате. import QtQuickimport QtQuick.ControlsWindow { width: 640 height: 480 visible: tr…

                                Следите за нами в социальных сетях