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. Getting values from a Huge String format= ("value : number")

Getting values from a Huge String format= ("value : number")

Scheduled Pinned Locked Moved General and Desktop
15 Posts 4 Posters 4.0k 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.
  • K Offline
    K Offline
    kamhagh
    wrote on 23 May 2015, 06:56 last edited by
    #1

    I'm not sure how i should do this, i'm really bad at strings
    but after i execute a linux shell command using QProcess it gives me this(with diffrent values):

    Default Adapter - AMD Radeon HD 7700 Series
    Core (MHz) Memory (MHz)
    Current Clocks : 1020 1125
    Current Peak : 1020 1125
    Configurable Peak Range : [300-1300] [150-1300]
    GPU load : 23%

    and i want to make the gpu load appear on a widget and do the same for current clocks, I have already made the widget that displays percent but the problem is i'm not sure how to get the GPU load value so i can give it to my widget

    also the percent might change to 100% so its not always 2 characters, the same is for current clocks otherwise i would use indexOf and use mid(indexOf,2);
    also i have to make it an int, which i guess toInt does the job

    can anyone help me with this?

    P 1 Reply Last reply 23 May 2015, 07:04
    0
    • K kamhagh
      23 May 2015, 06:56

      I'm not sure how i should do this, i'm really bad at strings
      but after i execute a linux shell command using QProcess it gives me this(with diffrent values):

      Default Adapter - AMD Radeon HD 7700 Series
      Core (MHz) Memory (MHz)
      Current Clocks : 1020 1125
      Current Peak : 1020 1125
      Configurable Peak Range : [300-1300] [150-1300]
      GPU load : 23%

      and i want to make the gpu load appear on a widget and do the same for current clocks, I have already made the widget that displays percent but the problem is i'm not sure how to get the GPU load value so i can give it to my widget

      also the percent might change to 100% so its not always 2 characters, the same is for current clocks otherwise i would use indexOf and use mid(indexOf,2);
      also i have to make it an int, which i guess toInt does the job

      can anyone help me with this?

      P Offline
      P Offline
      p3c0
      Moderators
      wrote on 23 May 2015, 07:04 last edited by
      #2

      @kamhagh If the number of lines are fixed then you can get the exact line i.e here 6th and then split it using section with : as seperator.

      157

      K 1 Reply Last reply 23 May 2015, 07:06
      1
      • P p3c0
        23 May 2015, 07:04

        @kamhagh If the number of lines are fixed then you can get the exact line i.e here 6th and then split it using section with : as seperator.

        K Offline
        K Offline
        kamhagh
        wrote on 23 May 2015, 07:06 last edited by kamhagh
        #3

        @p3c0 Thanks for your answer
        The problem is sometimes the GPU name might be Long or the user might have More than 1 graphics card. I don't think its a reliable solution!

        is there anyway i can take out the line as a separate String if i know the first word index? indexOf can find the "GPU Load :"

        P 1 Reply Last reply 23 May 2015, 07:13
        0
        • K kamhagh
          23 May 2015, 07:06

          @p3c0 Thanks for your answer
          The problem is sometimes the GPU name might be Long or the user might have More than 1 graphics card. I don't think its a reliable solution!

          is there anyway i can take out the line as a separate String if i know the first word index? indexOf can find the "GPU Load :"

          P Offline
          P Offline
          p3c0
          Moderators
          wrote on 23 May 2015, 07:13 last edited by
          #4

          @kamhagh Well then find the line which will have the string "GPU Load" using contains.

          157

          K 1 Reply Last reply 23 May 2015, 08:52
          1
          • P p3c0
            23 May 2015, 07:13

            @kamhagh Well then find the line which will have the string "GPU Load" using contains.

            K Offline
            K Offline
            kamhagh
            wrote on 23 May 2015, 08:52 last edited by
            #5

            @p3c0 thanks!
            but how can i take out that line using indexOf?(contains only returns true or false)

            P 1 Reply Last reply 23 May 2015, 09:34
            0
            • K kamhagh
              23 May 2015, 08:52

              @p3c0 thanks!
              but how can i take out that line using indexOf?(contains only returns true or false)

              P Offline
              P Offline
              p3c0
              Moderators
              wrote on 23 May 2015, 09:34 last edited by
              #6

              @kamhagh If that string is new line separated ("\n"), as it seems, split it into different strings, iterate and then check in it using contains

              QStringList list = outstr.split("\n");
              foreach(QString str, list) {
                  if(str.contains("GPU load"))
                      qDebug() << str.section(":",-1);
              }
              

              157

              1 Reply Last reply
              1
              • C Offline
                C Offline
                Chris Kawa
                Lifetime Qt Champion
                wrote on 23 May 2015, 12:06 last edited by
                #7

                Split and a loop can be a slow operation if the searched string is long. It also creates a lot of copies.
                On a large inputs a faster, more memory friendly and a little more permissive of the format solution would be to use a regexp, e.g.:

                auto options = QRegularExpression::CaseInsensitiveOption;
                auto m = QRegularExpression(".*GPU load[\\s:]+([\\d.]+)%", options).match(text);
                if(m.hasMatch()) {
                    float value = m.capturedRef(m.lastCapturedIndex()).toFloat();
                    // do something with value
                }
                

                This allows varying amount of whitespace between the "GPU load" and the actual number and will tolerate a number in any "C" locale form e.g. 7%, 42%, 100%, 4.54534345% etc.
                Note that QStringref::toFloat will work only for "C" locale i.e XXX.XXX% format.
                If you expect anything else, e.g. comma instead of dot or thousand separators you should use QLocale::toFloat instead and modify the regexp accordingly.

                K 1 Reply Last reply 23 May 2015, 17:10
                1
                • C Chris Kawa
                  23 May 2015, 12:06

                  Split and a loop can be a slow operation if the searched string is long. It also creates a lot of copies.
                  On a large inputs a faster, more memory friendly and a little more permissive of the format solution would be to use a regexp, e.g.:

                  auto options = QRegularExpression::CaseInsensitiveOption;
                  auto m = QRegularExpression(".*GPU load[\\s:]+([\\d.]+)%", options).match(text);
                  if(m.hasMatch()) {
                      float value = m.capturedRef(m.lastCapturedIndex()).toFloat();
                      // do something with value
                  }
                  

                  This allows varying amount of whitespace between the "GPU load" and the actual number and will tolerate a number in any "C" locale form e.g. 7%, 42%, 100%, 4.54534345% etc.
                  Note that QStringref::toFloat will work only for "C" locale i.e XXX.XXX% format.
                  If you expect anything else, e.g. comma instead of dot or thousand separators you should use QLocale::toFloat instead and modify the regexp accordingly.

                  K Offline
                  K Offline
                  kamhagh
                  wrote on 23 May 2015, 17:10 last edited by
                  #8

                  @Chris-Kawa thanks! that looks wierd, and like alien language to me but i'm googling about regexp! and than i guess i'll figure it out :D

                  C 1 Reply Last reply 23 May 2015, 17:22
                  0
                  • K kamhagh
                    23 May 2015, 17:10

                    @Chris-Kawa thanks! that looks wierd, and like alien language to me but i'm googling about regexp! and than i guess i'll figure it out :D

                    C Offline
                    C Offline
                    Chris Kawa
                    Lifetime Qt Champion
                    wrote on 23 May 2015, 17:22 last edited by
                    #9

                    @kamhagh said:

                    thanks! that looks wierd, and like alien language to me

                    haha. To you and me both ;) Regexps should not be the first thing to go to in most cases but they are powerful and should land in every programmer's toolbox at some point. They are great at parsing blocks of text and flexibly extracting pieces of it.

                    Basically in this case the interesting part of the regexp is the ([\\d.]+) part. The () is a capture group. Anything matched in that will be placed in an array of results accessed by capturedRef(). The []+ part says "anything inside the brackets at least once". \\d means "any digit" and . is, well, a dot character.
                    Other stuff: .* means "any character 0 or more times", [\\s:]+ means "at least one whitespace or :".
                    The \\ are unfortunate result of c++ standard. The actual characters needed by regexp are just \, but since it's in a c++ string literal we need to escape it and thus it becomes \\.

                    K 1 Reply Last reply 23 May 2015, 18:36
                    1
                    • C Chris Kawa
                      23 May 2015, 17:22

                      @kamhagh said:

                      thanks! that looks wierd, and like alien language to me

                      haha. To you and me both ;) Regexps should not be the first thing to go to in most cases but they are powerful and should land in every programmer's toolbox at some point. They are great at parsing blocks of text and flexibly extracting pieces of it.

                      Basically in this case the interesting part of the regexp is the ([\\d.]+) part. The () is a capture group. Anything matched in that will be placed in an array of results accessed by capturedRef(). The []+ part says "anything inside the brackets at least once". \\d means "any digit" and . is, well, a dot character.
                      Other stuff: .* means "any character 0 or more times", [\\s:]+ means "at least one whitespace or :".
                      The \\ are unfortunate result of c++ standard. The actual characters needed by regexp are just \, but since it's in a c++ string literal we need to escape it and thus it becomes \\.

                      K Offline
                      K Offline
                      kamhagh
                      wrote on 23 May 2015, 18:36 last edited by kamhagh
                      #10

                      @Chris-Kawa
                      thanks! now I understand!

                      But I get this while trying to compile:

                      **C:\Qt\Qt5.3.0\Tools\QtCreator\bin\regexTemp\main.cpp:14: error: 'options' does not name a type
                      auto options = QRegularExpression::CaseInsensitiveOption;
                      ^

                      C:\Qt\Qt5.3.0\Tools\QtCreator\bin\regexTemp\main.cpp:15: error: 'm' does not name a type
                      auto m = QRegularExpression(".*GPU load[\s:]+([\d.]+)%", options).match(outstr);
                      ^

                      C:\Qt\Qt5.3.0\Tools\QtCreator\bin\regexTemp\main.cpp:16: error: 'm' was not declared in this scope
                      if(m.hasMatch()) {
                      ^
                      ^**

                      after i add c++11 option to .pro file i get these

                      C:\Qt\Qt5.3.0\Tools\QtCreator\bin\regexTemp\main.cpp:14: error: incomplete type 'QRegularExpression' used in nested name specifier
                      auto options = QRegularExpression::CaseInsensitiveOption;
                      ^

                      C:\Qt\Qt5.3.0\Tools\QtCreator\bin\regexTemp\main.cpp:15: error: invalid use of incomplete type 'class QRegularExpression'
                      auto m = QRegularExpression(".*GPU load[\s:]+([\d.]+)%", options).match(outstr);
                      ^
                      C:\Qt\Qt5.3.0\5.3\mingw482_32\include\QtCore\qstring.h:78: error: forward declaration of 'class QRegularExpression'
                      class QRegularExpression;
                      ^

                      1 Reply Last reply
                      0
                      • C Offline
                        C Offline
                        Chris Kawa
                        Lifetime Qt Champion
                        wrote on 23 May 2015, 18:37 last edited by
                        #11

                        You are missing an include: #include <QRegularExpression>.

                        K 1 Reply Last reply 23 May 2015, 18:42
                        1
                        • C Chris Kawa
                          23 May 2015, 18:37

                          You are missing an include: #include <QRegularExpression>.

                          K Offline
                          K Offline
                          kamhagh
                          wrote on 23 May 2015, 18:42 last edited by kamhagh
                          #12

                          @Chris-Kawa
                          oh..... im going to kill myself :| how could I forget about that:D sorry!

                          thanks a lot!

                          but one last question, Do stuff like Program save files(quake arena if you've ever played it, or warcraft, basically old games or metro!) or Raspberry pi's setting(these are all i can think of + MSI Afterburner) use regexps to read save files?

                          1 Reply Last reply
                          0
                          • SGaistS Offline
                            SGaistS Offline
                            SGaist
                            Lifetime Qt Champion
                            wrote on 23 May 2015, 20:11 last edited by
                            #13

                            Hi,

                            If you want to toy around with QRegularExpression, a new version of the regexp tool can be found in examples/widgets/tools/regularexpression. It might be available only in the dev branch currently but you can build it with any Qt version including QRegularExpression.

                            Hope it helps

                            Interested in AI ? www.idiap.ch
                            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                            1 Reply Last reply
                            1
                            • C Offline
                              C Offline
                              Chris Kawa
                              Lifetime Qt Champion
                              wrote on 23 May 2015, 20:26 last edited by
                              #14

                              There's no way to say how these programs parse their files without looking at their source but I doubt they use regexps for that.

                              Regexps are best when the content you want to parse is fuzzy e.g. it can be uppercase, lowercase, spaces or tabs, comma or dot, unknown or partially known data patterns etc.
                              A user input of some sort or a spill from some diagnostic tool are good examples, where you want to just grab a piece of data you know the format of and don't care about its surrounding.

                              If you design your own app and thus define the format of your files you know what is where and you can assume stuff to make the parsing faster e.g "ABC tag always comes after XYZ tag so don't bother to check for it before".
                              In that case an incremental or structured parser can be a better and a lot faster solution. Regexp are flexible but come at a cost. They're sort of a heavy artillery of parsers.
                              An example of structural parser is QSettings used with QSettings::IniFormat to parse .ini files or a QDomDocument to parse an xml.
                              An example of incremental parser is a QXmlStreamReader that provides way to read an xml file "a token at a time" and decide what to do with it.

                              K 1 Reply Last reply 25 May 2015, 06:40
                              0
                              • C Chris Kawa
                                23 May 2015, 20:26

                                There's no way to say how these programs parse their files without looking at their source but I doubt they use regexps for that.

                                Regexps are best when the content you want to parse is fuzzy e.g. it can be uppercase, lowercase, spaces or tabs, comma or dot, unknown or partially known data patterns etc.
                                A user input of some sort or a spill from some diagnostic tool are good examples, where you want to just grab a piece of data you know the format of and don't care about its surrounding.

                                If you design your own app and thus define the format of your files you know what is where and you can assume stuff to make the parsing faster e.g "ABC tag always comes after XYZ tag so don't bother to check for it before".
                                In that case an incremental or structured parser can be a better and a lot faster solution. Regexp are flexible but come at a cost. They're sort of a heavy artillery of parsers.
                                An example of structural parser is QSettings used with QSettings::IniFormat to parse .ini files or a QDomDocument to parse an xml.
                                An example of incremental parser is a QXmlStreamReader that provides way to read an xml file "a token at a time" and decide what to do with it.

                                K Offline
                                K Offline
                                kamhagh
                                wrote on 25 May 2015, 06:40 last edited by
                                #15

                                @Chris-Kawa
                                oh thanks, I just thought it's always faster than doing that!

                                and thanks @SGaist i will take a look at that!

                                1 Reply Last reply
                                0

                                1/15

                                23 May 2015, 06:56

                                • Login

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