Aug. 20, 2019, 7:04 a.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.
15
R

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

  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;
VZ

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

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

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

QList<QPair<QString, QString>> list_with_pair;
list_with_pair.push_back(QPair("key1", "value1"));

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

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

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

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

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

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

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

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... Попробую.

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

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

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

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

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

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

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

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

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

Евгений,

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

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

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

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

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

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

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

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

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

Comments

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

Hello, Dear Users of EVILEG!!!

If the site helped you, then support the development of the site financially, please.

You can do it by following ways:

Thank you, Evgenii Legotckoi

VL
Jan. 20, 2020, 12:42 p.m.
Vova Lebedev

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:60points,
  • Rating points-1
VL
Jan. 20, 2020, 12:33 p.m.
Vova Lebedev

C++ - Test 001. The first program and data types

  • Result:80points,
  • Rating points4
AP
Jan. 20, 2020, 5:48 a.m.
Anastassiya Polyakova

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

  • Result:57points,
  • Rating points-2
Last comments
Jan. 21, 2020, 2:12 p.m.
Docent

Полезная статья. Как всегда - то что надо. Добавлю ещё маленькую полезность - после установки tracer (88 строка) и перед выводом значений в lineEdit (91 строка) стоит добавить updatePositio…
Jan. 17, 2020, 2:31 a.m.
Andrej Jankovich

Выглядит как ошибка библиотеки. Расскажите подробно на какой платформе вы собираете проект (MinGW или MSVC) их версии и версии Qt.
D
Jan. 16, 2020, 12:06 p.m.
DENIZ1819

Доброго времени суток, не подскажите, что делать в данной ситуации, после того, как я сделал все вышеуказанные инструкции для подключения библиотеки к проекту?
Jan. 14, 2020, 5:33 a.m.
Evgenij Legotskoj

Рекомендую Wt, достаточно мощная вещь. Этот фреймворк может использоваться для написания сайтов на C++, либо можно использовать только отдельный компоненты, например только ORM. Но я не знаю, ка…
a
Jan. 14, 2020, 5:29 a.m.
ayb

Спасибо за инфу. Поиск качественной ORM привел меня только к sqlite_orm, но не подходит из-за необходимости полноценной поддержки c++14. Про framework Wt не слышал, спасибо за наводку.
Now discuss on the forum
Jan. 22, 2020, 6:06 a.m.
Pavel.K

Можете попробовать через Loader сделать, те cделать свой компонент ректангл с нужными вам полями и через Loader вызывать этот компонент , а через Connections прописать что ваш компонент отрисова…
Jan. 22, 2020, 4:25 a.m.
Pavel.K

Привет, кто-нибудь делал тестовый Json сервер , чтобы не просто через сокет ByteArray пересылать, а с клиента обрабатывать Post и get запросы? Буду очень признателен если у кого то есть пр…
Jan. 20, 2020, 5:06 p.m.
Aleksej Vnukov

возможно,но все что я увидел по этому поводу - так это работать с этим адресом, но старые решения на данный момент не работают
Jan. 20, 2020, 1:49 p.m.
Evgenij Legotskoj

Добрый день, Касательно удаления строк. Любой QTableView класс, или наследованый от него имеет метод selectionModel() , который возвращает QItemSelectionModel . А эта…
Jan. 20, 2020, 1:35 p.m.
Evgenij Legotskoj

Добрый день. В Qt по сути используется MV шаблон проектирования. Поскольку контроллер и представление объединены в представлении. Так что да, вы понимаете правильно суть Qt. Насчёт тормозов…
EVILEG
About
Services
© EVILEG 2015-2019
Recommend hosting TIMEWEB