KM
31 августа 2020 г. 13:53

не знаю как исправить ошибуку QList<T>::at: "index out of range", при попытке вчитать QPoint с текстового файла

Qt, QPoint

void ToolBar::on_pushButton_clicked()
{

  1. QFile file("C:/Users/kamil/Desktop/data.txt");
  2. QList<QPointF> pointsList;
  3.  
  4.  
  5.  
  6. if(file.open(QIODevice::ReadOnly | QFile::Text)){
  7.  
  8. QTextStream in(&file);
  9.  
  10. while (!in.atEnd())
  11.  
  12. {
  13. QString line = in.readLine();
  14. QStringList points = line.split(';');
  15.  
  16. if (points.length() > 0)
  17.  
  18. {
  19. QPointF point(points.at(0).toDouble(), points.at(1).toDouble());
  20. pointsList.append(point); // и добавляем её в список
  21. }
  22.  
  23. }
  24.  
  25. file.close();
  26.  
  27. }

}

мой файл : 186,77;662,308;645,195; (Тут три точки которые я хочу нарисовать)
Буду очень благодарна за помощь!

3

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

5
Andrei Yankovich
  • 31 августа 2020 г. 13:59
  • (ред.)

Никогда не используйте метод at. это не безопасно, в место него используйте метод value. скорее всего в вашем случае у вас нет елемента под номером 1 в вашем списке.

Метот at нужно использовать только тогда когда вам нужна ссылка или указатель на обьект внутри массива.

В коде ошибка в неправельном использовании сепаратора:

  1. QStringList points = line.split(';');

если значения точки разделины ",".

  1. QStringList points = line.split(',');
    Evgenii Legotckoi
    • 31 августа 2020 г. 14:00

    Добрый день.

    Я правильно понимаю, что по факту в том файле ваши три точки выглядят так?

    186,77;
    662,308;
    645,195;

    То есть в столбик, а не в строку?

    Если так, то возможно стоит или сразу считать весь файл, то есть так QString line = in.readAll();

    Или сначала считать в вектор все строчки, а потом сформировать точки. Но сначала уточните по содержимому файла.

    Просто получается, что по факту этот кусок QStringList points = line.split(';'); не формирует правильный список точек и там внутри всего одна строчка, поскольку по факту точки написаны в столбик.

    P/S/ Используйте пожалуйста диалог вставки программного кода, это одна из кнопок в тулбаре редактора сообщений. Чтобы разметка правильно добавлялась для программного кода.

      Evgenii Legotckoi
      • 31 августа 2020 г. 14:07

      at() возвращает константную ссылку на объект внутри массива. Согласен, что это не безопасно, если может быть выход за пределы массива, но и с использованием value я бы тоже не согласился, поскольку данный метод сконструирует переменную с параметрами по умолчанию, которая в рамках программы будет тоже не правильной. И тут возникнет другая проблема, если в случае at программа просто упадёт, то место проблемы локализуется сразу, а если будут прилетать неправильные значения, то в большом проекте можно неделю убить, чтобы найти, откуда появляется лишняя точка с неправильными данными. Тут кстати как раз этот случай.

      Поэтому я бы не был так категоричен, чтобы не использовать at вообще.

      К тому же вопрос производительности. Создание нового объекта также может быть затратным, гораздо затратнее, чем взять константную ссылку на объект.

        KM
        • 1 сентября 2020 г. 13:45
        • (ред.)

        у меня идет отрисовка фигур и на пример к каждому треугольнику три точки в линию следующий треугольник опять линия с тремя точкая и тд.
        Выходит как вы говорите столбик но каждая линия в нем отдельная фигура.

        1. 195,76;437,282;428,124; // первый треугольник
        2. 195,76;437,282;428,124;// второй треугольник
          KM
          • 1 сентября 2020 г. 13:48
          • (ред.)

          Это два отдельных сепаратора
          класс RectToDraw, закоментировала пример точки и ее сепараторов.

          1. readFromString = "144,81:626,232"
          2. const QString &rectInString = ':'
          3. char pointsSplitter = ','
          4.  
          5.  
          6. void RectToDraw::readFromString(const QString &rectInString, char pointsSplitter, char xySplitter)
          7. {
          8. QStringList point = rectInString.split(pointsSplitter);
          9. //point ("144,81", "626,232")
          10. if(point.count()!=2) return;
          11. QStringList xy1 = point.at(0).split(xySplitter);//xy1("144","81")
          12. QStringList xy2 = point.at(1).split(xySplitter);
          13.  
          14. setTopLeft(QPointF(xy1.at(0).toFloat(), xy1.at(1).toFloat()));
          15. setBottomRight(QPointF(xy2.at(0).toFloat(), xy2.at(1).toFloat()));
          16.  
          17. }

            Комментарии

            Только авторизованные пользователи могут публиковать комментарии.
            Пожалуйста, авторизуйтесь или зарегистрируйтесь
            • Последние комментарии
            • IscanderChe
              12 апреля 2025 г. 17:12
              Добрый день. Спасибо Вам за этот проект и отдельно за ответы на форуме, которые мне очень помогли в некоммерческих пет-проектах. Профессиональным программистом я так и не стал, но узнал мно…
            • AK
              1 апреля 2025 г. 11:41
              Добрый день. В данный момент работаю над проектом, где необходимо выводить звук из программы в определенное аудиоустройство (колонки, наушники, виртуальный кабель и т.д). Пишу на Qt5.12.12 поско…
            • Evgenii Legotckoi
              9 марта 2025 г. 21:02
              К сожалению, я этого подсказать не могу, поскольку у меня нет необходимости в обходе блокировок и т.д. Поэтому я и не задавался решением этой проблемы. Ну выглядит так, что вам действитель…
            • VP
              9 марта 2025 г. 16:14
              Здравствуйте! Я устанавливал Qt6 из исходников а также Qt Creator по отдельности. Все компоненты, связанные с разработкой для Android, установлены. Кроме одного... Когда пытаюсь скомпилиров…
            • ИМ
              22 ноября 2024 г. 21:51
              Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…