Russian Qt Forum

Qt => Вопросы новичков => Тема начата: tr1bls от Март 05, 2017, 10:16



Название: QLineEdit
Отправлено: tr1bls от Март 05, 2017, 10:16
Имеется QLineEdit, в который через пробел вводятся вещественные числа. Каким образом можно заполнить массив действительных чисел числами из этой строки?


Название: Re: QLineEdit
Отправлено: vic57 от Март 05, 2017, 13:12
Код
C++ (Qt)
QStringList l = lineEdit.text().split(" ");
QVector<double> v;
QString s;
foreach(s,l) v += s.toDouble();
 


Название: Re: QLineEdit
Отправлено: titan83 от Март 05, 2017, 15:38
vic57, ваше решение абсолютно рабочее, но все же предложу свое без foreach (который уже давненько deprecated) и с C++11 (который уже неплохо бы использовать).
Код:
    QLineEdit* editor = new QLineEdit();
    QVector<double> v;
    editor->setText("6.488 -5 0.995");
    for (QString number : editor->text().split(' '))
        v.append(number.toDouble());
    qDebug() << "text" << editor->text() << "array" << v;
    delete(editor);


Название: Re: QLineEdit
Отправлено: Igors от Март 10, 2017, 15:18
vic57, ваше решение абсолютно рабочее, но все же предложу свое без foreach (который уже давненько deprecated) и с C++11 (который уже неплохо бы использовать).
Код:
    QLineEdit* editor = new QLineEdit();
    QVector<double> v;
    editor->setText("6.488 -5 0.995");
    for (QString number : editor->text().split(' '))
        v.append(number.toDouble());
    qDebug() << "text" << editor->text() << "array" << v;
    delete(editor);
Допустим юзер где-то ошибся напр в одном числе запятая вместо точки. Хорошо бы дать ему от ворот поворот и подсветить в QLineEdit это калечное число. Будет ли решение на С++ 11 выразительнее и/или лаконичнее? Или практически такое же как на С++ 99 ?


Название: Re: QLineEdit
Отправлено: __Heaven__ от Март 10, 2017, 15:54
А мой вариант был бы
Код
C++ (Qt)
QVector<double> result;
for (const QString &strValue: lineEdit->text().split(' ')) {
   result << strValue.toDouble();
}

А для всякого рода проверок завёл бы валидатор lineEdit.


Название: Re: QLineEdit
Отправлено: Пантер от Март 10, 2017, 16:00
Как после Пайтона не хватает вот такого синтаксиса:
Код
C++ (Qt)
const auto result = [s.toDouble() for s in lineEdit->text().split(' ')]
 


Название: Re: QLineEdit
Отправлено: __Heaven__ от Март 10, 2017, 16:57
Wut?!


Название: Re: QLineEdit
Отправлено: kambala от Март 10, 2017, 17:23
Как после Пайтона не хватает вот такого синтаксиса:
Код
C++ (Qt)
const auto result = [s.toDouble() for s in lineEdit->text().split(' ')]
 
можно blockingMap из QtConcurrent заюзать :)


Название: Re: QLineEdit
Отправлено: Пантер от Март 10, 2017, 18:47
Wut?!
Я о том, что в Пайтоне очень красиво такая задача бы решалась:

Код
Python
s = '1.5 2.6 3.7 4.8'
result = [float(i) for i in s.split(' ')]
 


Название: Re: QLineEdit
Отправлено: __Heaven__ от Март 10, 2017, 21:48
Я понял :)
С непривычки синтаксис выглядит как "чё за хрень здесь творится!?" А так да, человекочитабельненько


Название: Re: QLineEdit
Отправлено: titan83 от Март 12, 2017, 15:26
vic57, ваше решение абсолютно рабочее, но все же предложу свое без foreach (который уже давненько deprecated) и с C++11 (который уже неплохо бы использовать).
Код:
    QLineEdit* editor = new QLineEdit();
    QVector<double> v;
    editor->setText("6.488 -5 0.995");
    for (QString number : editor->text().split(' '))
        v.append(number.toDouble());
    qDebug() << "text" << editor->text() << "array" << v;
    delete(editor);
Допустим юзер где-то ошибся напр в одном числе запятая вместо точки. Хорошо бы дать ему от ворот поворот и подсветить в QLineEdit это калечное число. Будет ли решение на С++ 11 выразительнее и/или лаконичнее? Или практически такое же как на С++ 99 ?
C++11 будет лаконичнее однозначно.
Взять хотя бы лямбды, можно сразу убрать одноразовые слоты длиной в одну-две строки.


Название: Re: QLineEdit
Отправлено: Igors от Март 17, 2017, 11:06
Допустим юзер где-то ошибся напр в одном числе запятая вместо точки. Хорошо бы дать ему от ворот поворот и подсветить в QLineEdit это калечное число. Будет ли решение на С++ 11 выразительнее и/или лаконичнее? Или практически такое же как на С++ 99 ?
C++11 будет лаконичнее однозначно.
Прошу исполнить

Я о том, что в Пайтоне очень красиво такая задача бы решалась:

Код
Python
s = '1.5 2.6 3.7 4.8'
result = [float(i) for i in s.split(' ')]
 
И если слово не float? 


Название: Re: QLineEdit
Отправлено: Пантер от Март 17, 2017, 11:53
Упадет эксепшен.


Название: Re: QLineEdit
Отправлено: titan83 от Март 17, 2017, 20:23
Допустим юзер где-то ошибся напр в одном числе запятая вместо точки. Хорошо бы дать ему от ворот поворот и подсветить в QLineEdit это калечное число. Будет ли решение на С++ 11 выразительнее и/или лаконичнее? Или практически такое же как на С++ 99 ?
C++11 будет лаконичнее однозначно.
Прошу исполнить

Код:
    QLineEdit edit;
    edit.setText("lox 123 4,5 lox100500 -34.66");
    QStringList numbersList, elementsList;
    QRegularExpressionMatchIterator i = QRegularExpression("(?<!\\S)([-]?\\d+[.,]?\\d*)(?!\\S)").globalMatch(edit.text());
    while (i.hasNext())
        numbersList.append(i.next().captured(1));
    i = QRegularExpression("(\\S+)").globalMatch(edit.text());
    while (i.hasNext())
        elementsList.append(i.next().captured(1));
    for (auto element : elementsList)
        if (numbersList.contains(element) == false)
            qDebug() << "bad" << element;


Название: Re: QLineEdit
Отправлено: kambala от Март 18, 2017, 12:15
щас тема опять скатится в обсуждение «регулярки/спирит vs велосипед-токенайзер»


Название: Re: QLineEdit
Отправлено: titan83 от Март 18, 2017, 12:53
щас тема опять скатится в обсуждение «регулярки/спирит vs велосипед-токенайзер»
Вы правы, поэтому, думаю, стоит тему закрывать. А то Igors сейчас погонит волну))


Название: Re: QLineEdit
Отправлено: titan83 от Март 18, 2017, 13:22
Но перед закрытием улучшу свой вариант:
Код:
    QLineEdit edit;
    edit.setText("lox 123 4,5 lox100500 -34.66");
    QSet<QString> numbersList;
    QSet<QString> elementsList;
    QRegularExpressionMatchIterator i = QRegularExpression("(?<!\\S)([-]?\\d+[.,]?\\d*)(?!\\S)").globalMatch(edit.text());
    while (i.hasNext())
        numbersList.insert(i.next().captured(1));
    i = QRegularExpression("(\\S+)").globalMatch(edit.text());
    while (i.hasNext())
        elementsList.insert(i.next().captured(1));
    qDebug() << "bad set" << elementsList.subtract(numbersList);


Название: Re: QLineEdit
Отправлено: Igors от Март 22, 2017, 11:25
А то Igors сейчас погонит волну))
:)

Но перед закрытием улучшу свой вариант:
Код:
    QLineEdit edit;
    edit.setText("lox 123 4,5 lox100500 -34.66");
    QSet<QString> numbersList;
    QSet<QString> elementsList;
    QRegularExpressionMatchIterator i = QRegularExpression("(?<!\\S)([-]?\\d+[.,]?\\d*)(?!\\S)").globalMatch(edit.text());
    while (i.hasNext())
        numbersList.insert(i.next().captured(1));
    i = QRegularExpression("(\\S+)").globalMatch(edit.text());
    while (i.hasNext())
        elementsList.insert(i.next().captured(1));
    qDebug() << "bad set" << elementsList.subtract(numbersList);
Вот есть прекрасные сишные ф-ции strtol и strtod. Они пропускают символы-пробелы, считывают число и останавливаются на символе который уже не число. Разве нельзя реализовать то же самое с QString? Неужели для простейшей задачи "считать флоты разделенные пробелами" действительно необходимы два контейнера и два итератора (да еще и обширные познания в регулярке)? В итоге все равно получился велосипед - но он просто ужасен  :)


Название: Re: QLineEdit
Отправлено: Racheengel от Март 22, 2017, 12:42
А еще есть QString::split с параметром QString::SkipEmptyParts.
Получается список токенов на выходе, а их можно уже проверять на число.

Или есть QTextStream, который умеет работать со строками и через >> можно читать числа.

Но strtol и strtod, действительно, заточены именно под такую задачу :)