How to search for a specific character in a QString



  • Hi,

    Consider we have a QString and we want to search for a character in it.

    What method is best for it and what does it return when that character is found or not please?


  • Lifetime Qt Champion

    Hi,

    What about QString::contains ?



  • or

    bool ClassName::containLetter(QChar letter, QString myString)
    {
    foreach(QChar char, myString)
    if(letter== char)
    return true;
    return false;
    }


  • Lifetime Qt Champion

    @Artmetic why reinvent the wheel when the function is already available ?



  • Yes it is avaible, but everything depends of the problem. The use of your solution is probably optimalized and faster, but of course it depends :)


  • Moderators

    @tomy Taking a short look at Qt documentation you would be able to answer your question by yourself...



  • @SGaist
    Good solution, but what if we want to know "the index of that QChar" if exists?

    @jsulm
    Good thanks. How should I look for a specific method while apparently there are thousands methods on Qt documentations? For example I want the index of a specific char in a string (if that exists), what is an optimized way to look for it?

    PS: Of course I can use a simple for loop but when there is method already, why increase lines of code by loops!



  • @tomy

    the answer would be

    int QString::indexOf(const QString &str, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
    

    ;)

    straight from the docu, 10 seconds search. Once you have some kind of routine, the docu is realy fast and good to navigate.



  • Thanks, but it does not work OK always. For example consider these:

    double d = 12000000;
    QString s = QString::number(d);
     int point = s.indexOf('.');
     lineEdit -> setText(QString::number(point));
    

    The result is 1!
    Using this one too:

    double d = 12000000;
    QString s;
    QTextStream ss(&s);
    ss << d;
    int point = s.indexOf('.')
    lineEdit -> setText(QString::number(point));
    

    The result is 1 again!



  • @tomy Dude, the answer "1" is spot on accurate.

    If you display the result of QString::number(12000000) you'll get "1.2e+07" == 1.2 * 10^7 == 1.2 * 10000000 == 12000000.

    Therefore the '.' is the second character e.g. index '1'.

    Try QString::number(d, 'f', 0). That should work as it will output 12000000 and s.indexof('.') will return -1 (if that's what you want).



  • There will not be any dot in other numbers, say, 12.21! Because we have used '0' as the precision!



  • @tomy Precisely. Your example was of an integer number, albeit packed into a double (there is adequate precision for your example)

    If you ask for extra precision you will get extra '0's after the decimal point. I don't know if this is what you want.

    What is it you are trying to do?! If you are justing searching for characters use indexOf. Is this is something to do with figuring out how many digits are required to display a number? In which case use math functions such as floor, ceiling and log10. If you want to know about the fractional parts use X-floor(X).

    The example you gave does work. Just not the way you want it too and that was not what you originally asked for.


  • Lifetime Qt Champion

    Also, why not use a QDoubleSpinBox to show your numbers ?


  • Moderators

    @tomy How? Well, you know it is QString so take a look at its documentation. QString doesn't have "thousands" of methods.



  • @matthew.kuiash

    What I need is showing a double result. It may be a very small negative/positive number (say, -0.000000001234) or a very big positive/negative number (say, +2500000000036540). It's range I should cover by code.

    I only need the 'number of' digits after the decimal point. Then I will use another method to use 'that number' precision for the output.

    @SGaist:
    Very good info, thanks.
    But the lineEdit there, is used to "show" the result of a calculation. (My calculator works fine but I just want to make it more precise).
    QDoubleSpinBox has two buttons and works in essence like an editable cadre, while I just need "to show" the result (and also save the current result for the next expressions).



  • double d = 12000000.0;
    QString s = QString::number(d,'f',std::numeric_limits<decltype(d)>::max_digits10);
    if(s.contains('.')){
    int i=s.size()-1;
    for(;s.at(i)=='0';--i){}
    s=s.left(i+ (s.at(i)=='.' ? 0:1));
    }
    

    Edit:

    alternative:

    // needs #include <cmath>
    double d = 12000000.0;
    double junk;
    int precision=0;
    for(double tester=d;!qFuzzyIsNull(std::modf(tester,&junk));++precision,tester*=10.0){}
    QString s = QString::number(d,'f',precision);
    


  • @VRonin
    Thank you.

    Both have flaws. But also both have high level of precision.
    I think the flaws belong to the way numbers are stored in registers. And I think there is no completely (100%) accurate calculator in the world because of that.

    I chose the latter. Thanks for your help. I'm appreciative.



  • @tomy OK. You have plenty to go on here but I'll just caution you that the number of digits after the decimal point can be extremely high for doubles.



  • @matthew.kuiash
    I have used as high precision as possible for doubles using VRonin's code.
    I think I'm at the end. The differences between what we expect and what is shown using the code may happen for low of high precisions because of the difference of the way we and the machine calculate expressions.



  • Hi @tomy. QDoubleSpinBox can be used as you mentioned . First, to hide buttons call QAbstractSpinBox::setButtonSymbols(ButtonSymbols bs) and second call QAbstractSpinBox::setReadOnly(bool r).
    Have a nice day.



  • QDoubleSpinBox can be used as you mentioned

    You still have to hard code the precision (number of decimals) shown so it does not solve the problem

    The differences between what we expect and what is shown using the code may happen for low of high precisions

    The maximum number of digits that can be represented in text is is std::numeric_limits<double>::digits10, you can't get meaningful results if you go beyond this limit



  • @zapprox
    You pointed to a good matter —hiding the buttons of that widget. As SGaist had suggested it firstly, I would like to use it because I thought it would solve the problems of those double numbers we were involving since above posts. But when VRonin subsequently said, it seems that we don't get more benefits of it compared to the chosen code.

    Thank you all.


  • Qt Champions 2016

    Didn't we discuss these precision things recently, I have a distinct impression we are running a loop ...
    This thread comes to mind.



  • @kshegunov
    No.
    The earlier issue was about the way that makes us able to show our result (say, 1000000) in real number mode not scientific.
    But after that, (this thread), we should be able to show the number of the precision suitable for each number as a result.
    We don't want to e.g., show 12.25 as 12.25000000 (just because we are able to show number in real mode). For the matter of accuracy, the user of the app expects to see the result in a professional way.
    Hope this helps.

    PS: I wish we wouldn't have anything named "storing numbers in binary mode" and "scientific notation". ;)



  • I did not read the qFuzzyCompare documentation. shame on me. the compare to 0 should be avoided, corrected the snippet above



  • I use this:

       double tester = d;
        double junk;
        int precision = 0;
    
        for(;!qFuzzyCompare(0.0,std::modf(tester,&junk));++precision,tester*=10.0){}
        QString s = QString::number(d,'f',precision);
        return s;
    

    How might this face a problem please?
    I want to test it on the app.



  • @VRonin
    Hi VRonin,

    If you see any problem with the code written above in my prior post compared to your edited one, please point to it. If there is a flaw, I will use the edited one in the app.



  • from http://doc.qt.io/qt-5/qtglobal.html#qFuzzyCompare

    Note that comparing values where either p1 or p2 is 0.0 will not work

    so instead of qFuzzyCompare(0.0,std::modf(tester,&junk)) use qFuzzyIsNull(std::modf(tester,&junk))



  • I don't know why you have thought that the decimal part will always be zero.

    I've used this:

    qFuzzyCompare(1.0,1.0+std::modf(tester,&junk))
    


  • that will work too but the loop must go on untill the decimal part is 0 so qFuzzyIsNull is appropriate.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.