Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QStringList replaceInStrings feature or a bug?
Qt 6.11 is out! See what's new in the release blog

QStringList replaceInStrings feature or a bug?

Scheduled Pinned Locked Moved Solved General and Desktop
9 Posts 3 Posters 3.8k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • F Offline
    F Offline
    fantaz
    wrote on last edited by fantaz
    #1

    Consider the following example:

    QStringList mylist;
    mylist << "ONE" << "TWO"<<"THREE";
    QString after = "dummy";
    QString before; // same with QString before=""; 
    qDebug()<< mylist;
    mylist.replaceInStrings(before, after);
    qDebug()<< mylist;
    

    results in an output:

    ("ONE", "TWO", "THREE")
    ("dummyOdummyNdummyEdummy", "dummyTdummyWdummyOdummy", "dummyTdummyHdummyRdummyEdummyEdummy")
    

    The replaceInStrings function finds an empty string i.e. the before variable value "", and:

    • Appends the after string at the end of each string
    • Prepends the after string before each letter in every string in list

    Is this behavior intentional?

    jsulmJ 1 Reply Last reply
    0
    • F fantaz

      Consider the following example:

      QStringList mylist;
      mylist << "ONE" << "TWO"<<"THREE";
      QString after = "dummy";
      QString before; // same with QString before=""; 
      qDebug()<< mylist;
      mylist.replaceInStrings(before, after);
      qDebug()<< mylist;
      

      results in an output:

      ("ONE", "TWO", "THREE")
      ("dummyOdummyNdummyEdummy", "dummyTdummyWdummyOdummy", "dummyTdummyHdummyRdummyEdummyEdummy")
      

      The replaceInStrings function finds an empty string i.e. the before variable value "", and:

      • Appends the after string at the end of each string
      • Prepends the after string before each letter in every string in list

      Is this behavior intentional?

      jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @fantaz I don't know whether it is intentional. You could check the implementation of replaceInStrings.

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • F Offline
        F Offline
        fantaz
        wrote on last edited by fantaz
        #3

        If I'm not mistaken, this is the actual implementation:

        inline QStringList &QStringList::replaceInStrings(const QString &before, const QString &after, Qt::CaseSensitivity cs)
        {
            QtPrivate::QStringList_replaceInStrings(this, before, after, cs);
            return *this;
        }
        
        void QtPrivate::QStringList_replaceInStrings(QStringList *that, const QString &before,
                                                     const QString &after, Qt::CaseSensitivity cs)
        {
            for (int i = 0; i < that->size(); ++i)
                (*that)[i].replace(before, after, cs);
        }
        

        So, not testing on isEmpty on before QString.
        One could either put an if statement in an inline replaceInStrings or QPrivate implementation. I wouldn't know just how much would that slow down the function execution.
        I'm not quite sure if this edge case deserves special attention.
        On the other hand, the resulting outcome is quite peculiar. I wouldn't expect that the nothing would be replaced with the after string., since it's just that, nothing, an empty string. At least, it would be great if this behavior finds it's way in the documentation.
        Am I wrong on this one?

        jsulmJ 1 Reply Last reply
        0
        • F fantaz

          If I'm not mistaken, this is the actual implementation:

          inline QStringList &QStringList::replaceInStrings(const QString &before, const QString &after, Qt::CaseSensitivity cs)
          {
              QtPrivate::QStringList_replaceInStrings(this, before, after, cs);
              return *this;
          }
          
          void QtPrivate::QStringList_replaceInStrings(QStringList *that, const QString &before,
                                                       const QString &after, Qt::CaseSensitivity cs)
          {
              for (int i = 0; i < that->size(); ++i)
                  (*that)[i].replace(before, after, cs);
          }
          

          So, not testing on isEmpty on before QString.
          One could either put an if statement in an inline replaceInStrings or QPrivate implementation. I wouldn't know just how much would that slow down the function execution.
          I'm not quite sure if this edge case deserves special attention.
          On the other hand, the resulting outcome is quite peculiar. I wouldn't expect that the nothing would be replaced with the after string., since it's just that, nothing, an empty string. At least, it would be great if this behavior finds it's way in the documentation.
          Am I wrong on this one?

          jsulmJ Offline
          jsulmJ Offline
          jsulm
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @fantaz I think it is up to the developer to make sure the before string isn't empty. This behaviour could be handy actually if you want to put something between characters.

          https://forum.qt.io/topic/113070/qt-code-of-conduct

          F 1 Reply Last reply
          2
          • VRoninV Offline
            VRoninV Offline
            VRonin
            wrote on last edited by
            #5

            You missed a few points in the source, you needed to dig a bit deeper

            form QString::replace:

            if (d->size == 0) {
                    if (blen)
                        return *this;
                } else {
                    if (cs == Qt::CaseSensitive && before == after && blen == alen)
                        return *this;
                }
                if (alen == 0 && blen == 0)
            return *this;
            

            so there are checks and your case is explicitly excluded. I'm 100% sure this is an intended feature

            "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
            ~Napoleon Bonaparte

            On a crusade to banish setIndexWidget() from the holy land of Qt

            F 1 Reply Last reply
            1
            • jsulmJ jsulm

              @fantaz I think it is up to the developer to make sure the before string isn't empty. This behaviour could be handy actually if you want to put something between characters.

              F Offline
              F Offline
              fantaz
              wrote on last edited by
              #6

              @jsulm You're right.
              IMHO, the best way would be to document this kind of behavior, so that people would know what to expect it they accidentally provide an empty string as a before parameter.

              jsulmJ 1 Reply Last reply
              0
              • F fantaz

                @jsulm You're right.
                IMHO, the best way would be to document this kind of behavior, so that people would know what to expect it they accidentally provide an empty string as a before parameter.

                jsulmJ Offline
                jsulmJ Offline
                jsulm
                Lifetime Qt Champion
                wrote on last edited by
                #7

                @fantaz Agree, it should be documented. You can either provide a patch :-) or create a bug ticket for that.

                https://forum.qt.io/topic/113070/qt-code-of-conduct

                F 1 Reply Last reply
                0
                • VRoninV VRonin

                  You missed a few points in the source, you needed to dig a bit deeper

                  form QString::replace:

                  if (d->size == 0) {
                          if (blen)
                              return *this;
                      } else {
                          if (cs == Qt::CaseSensitive && before == after && blen == alen)
                              return *this;
                      }
                      if (alen == 0 && blen == 0)
                  return *this;
                  

                  so there are checks and your case is explicitly excluded. I'm 100% sure this is an intended feature

                  F Offline
                  F Offline
                  fantaz
                  wrote on last edited by
                  #8

                  @VRonin Thanks. I missed it!

                  1 Reply Last reply
                  0
                  • jsulmJ jsulm

                    @fantaz Agree, it should be documented. You can either provide a patch :-) or create a bug ticket for that.

                    F Offline
                    F Offline
                    fantaz
                    wrote on last edited by fantaz
                    #9

                    @jsulm Not smart enough to provide the patch, issued a bug ticket instead :-)

                    1 Reply Last reply
                    1

                    • Login

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • Users
                    • Groups
                    • Search
                    • Get Qt Extensions
                    • Unsolved