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. Modify a .txt file
QtWS25 Last Chance

Modify a .txt file

Scheduled Pinned Locked Moved Solved General and Desktop
15 Posts 7 Posters 3.2k 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.
  • V Offline
    V Offline
    viniltc
    wrote on 23 Jan 2020, 10:18 last edited by viniltc
    #1

    Hi all,

    I have a large .txt file containing settings to configure a serial device. I can access each lines of the file by doing this:

       QString filename = "config_keygrip";
       QString path = QCoreApplication::applicationDirPath()+"/"+filename+".txt";
       QFile file(path);
    
        if(!file.open(QIODevice::ReadOnly  | QIODevice::Text))
        {
            QMessageBox::information(this, "Unable to open file for read", file.errorString());
            return;
        }
    
        else
        {
            QTextStream in(&file);
    
            while(!in.atEnd())
            {
                QString line = in.readLine();
                QString trackName("O CH1");
                int pos = line.indexOf(trackName);
                if (pos >= 0)
    
                {
                    ui->textBrowser->setText(line) //--> to see the line 
                }
            }
    
            file.close();
        }
    

    In the above case the QString line read as:

    O CH2 0mA 0ms 0ms 600000ns 180us RATE

    Here how do I modify this line and write back to the original file?

    For example I want to replace number 180 with a different value get through a QSlider

    ui->verticalSlider_ch1->value()

    J 1 Reply Last reply 23 Jan 2020, 10:30
    1
    • V viniltc
      23 Jan 2020, 10:18

      Hi all,

      I have a large .txt file containing settings to configure a serial device. I can access each lines of the file by doing this:

         QString filename = "config_keygrip";
         QString path = QCoreApplication::applicationDirPath()+"/"+filename+".txt";
         QFile file(path);
      
          if(!file.open(QIODevice::ReadOnly  | QIODevice::Text))
          {
              QMessageBox::information(this, "Unable to open file for read", file.errorString());
              return;
          }
      
          else
          {
              QTextStream in(&file);
      
              while(!in.atEnd())
              {
                  QString line = in.readLine();
                  QString trackName("O CH1");
                  int pos = line.indexOf(trackName);
                  if (pos >= 0)
      
                  {
                      ui->textBrowser->setText(line) //--> to see the line 
                  }
              }
      
              file.close();
          }
      

      In the above case the QString line read as:

      O CH2 0mA 0ms 0ms 600000ns 180us RATE

      Here how do I modify this line and write back to the original file?

      For example I want to replace number 180 with a different value get through a QSlider

      ui->verticalSlider_ch1->value()

      J Offline
      J Offline
      JonB
      wrote on 23 Jan 2020, 10:30 last edited by JonB
      #2

      @viniltc
      This seems to get asked frequently here. Answered as simply as possible, you cannot update lines in a text file in situ, i.e. any kind of "open file for update and insert/remove a bit here". You have to either:

      • Read whole file into memory, makes changes in memory, overwrite existing file with whole new content.
      • Read a line at a time from file, changing as necessary, and writing that out a line at a time to a new, temporary file. On conclusion, delete original file and rename temporary file.
      1 Reply Last reply
      4
      • F Offline
        F Offline
        Fuel 0
        wrote on 23 Jan 2020, 10:34 last edited by
        #3

        Maybe not a clean Way, but you can split the Line and get the Value. Save the Value in a Variable and bind it to your Silder. Make a Save Button. When you save then build a new String and replace the complete Line. When you read the Line maybe you can count the Lines, so you know in which Line you have to replace everything. For that you need the complete File in a String or something. To write everything back is as easy as you read the File. Just overwrite everything.

        Thats the first Thing i would try, but perhaps someone has a better Solution.

        V 1 Reply Last reply 23 Jan 2020, 15:09
        2
        • O Offline
          O Offline
          ODБOï
          wrote on 23 Jan 2020, 10:43 last edited by ODБOï
          #4

          @viniltc hi

          for the read/write part you can use JSON document instead of plain text file, because it offers you convenient methods for "parsing" the file

          1 Reply Last reply
          3
          • M Offline
            M Offline
            mrjj
            Lifetime Qt Champion
            wrote on 23 Jan 2020, 10:52 last edited by mrjj
            #5

            Hi

            O CH2 0mA 0ms 0ms 600000ns 180us RATE

            Does all line have the same format ? (same positions of values)

            Also, do you write out this file your self ? ( so you can control the format)

            Also how big is big?

            For random editing, in-memory editing is far more fun than ON THE FLY change reading file line by line and
            then change a line before writing it back.
            However, it really depends on what the actual use case is.
            If only need to change one value, one time, it won't matter much :)

            V 1 Reply Last reply 23 Jan 2020, 11:19
            3
            • V Offline
              V Offline
              VRonin
              wrote on 23 Jan 2020, 10:55 last edited by VRonin
              #6

              I want to replace number 180 with a different value get through a QSlider

              Can the value be represented always with 3 digits (decimal or hex doesn't matter)?
              What encoding is the text file using?

              "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

              1 Reply Last reply
              3
              • M mrjj
                23 Jan 2020, 10:52

                Hi

                O CH2 0mA 0ms 0ms 600000ns 180us RATE

                Does all line have the same format ? (same positions of values)

                Also, do you write out this file your self ? ( so you can control the format)

                Also how big is big?

                For random editing, in-memory editing is far more fun than ON THE FLY change reading file line by line and
                then change a line before writing it back.
                However, it really depends on what the actual use case is.
                If only need to change one value, one time, it won't matter much :)

                V Offline
                V Offline
                viniltc
                wrote on 23 Jan 2020, 11:19 last edited by
                #7

                @JonB , @Fuel-0 @LeLev @mrjj Thanks a lot for your feedback. I'm sorry for my vague explanation.

                An incomplete configuration file looks like this:

                `R ref, version, "config_ID",                   menu language, Power timeout (hours), Number of users
                    R  R1   1        "Template for setting parameters"  ENGLISH        1                      1
                    
                    `U ref, "user name", language, volume, number of activities
                    U U1    "Any user"   ENGLISH   100%      1
                    
                    `A ref, "activity name",    max duration, max cycles, startingPW%, available/hidden
                     A A1   "Setup stim levels" 0min          0           0%           AVAILABLE FALSE FALSE TRUE TRUE
                    
                      B SA1 1 "Engine tests"
                    ` These limits apply to all phases
                    `  M ref stim, channel, max current, minPW, maxPW, freq, waveform, output name
                       M CH1 1 1 120mA 10us 450us 40Hz ASYM "Channel 1"
                       M CH2 1 2 120mA 10us 450us 40Hz ASYM "Channel 2"
                    
                       P P0 "Test phase" 0ms NONE 2000ms STOP STOP STOP
                    `                Delay  RR    rate    PW    
                        O CH1 0mA  0ms    0ms   600000ns 180us RATE   
                        O CH2 0mA  0ms    0ms   600000ns 180us RATE
                
                

                I basically need to change parameters in the last two lines of the file. I can access a particular line but don't know how to split the Line and get the Value. Here parameters are presented as a list of space-separated variables.

                p.s.
                The description is formatted as ASCII text. Multiple space characters are collapsed into one. Comments are enclosed in `` and replaced with space characters. A single backtick ` starts a comment that continues to the end of the line.

                J 1 Reply Last reply 23 Jan 2020, 11:28
                0
                • V viniltc
                  23 Jan 2020, 11:19

                  @JonB , @Fuel-0 @LeLev @mrjj Thanks a lot for your feedback. I'm sorry for my vague explanation.

                  An incomplete configuration file looks like this:

                  `R ref, version, "config_ID",                   menu language, Power timeout (hours), Number of users
                      R  R1   1        "Template for setting parameters"  ENGLISH        1                      1
                      
                      `U ref, "user name", language, volume, number of activities
                      U U1    "Any user"   ENGLISH   100%      1
                      
                      `A ref, "activity name",    max duration, max cycles, startingPW%, available/hidden
                       A A1   "Setup stim levels" 0min          0           0%           AVAILABLE FALSE FALSE TRUE TRUE
                      
                        B SA1 1 "Engine tests"
                      ` These limits apply to all phases
                      `  M ref stim, channel, max current, minPW, maxPW, freq, waveform, output name
                         M CH1 1 1 120mA 10us 450us 40Hz ASYM "Channel 1"
                         M CH2 1 2 120mA 10us 450us 40Hz ASYM "Channel 2"
                      
                         P P0 "Test phase" 0ms NONE 2000ms STOP STOP STOP
                      `                Delay  RR    rate    PW    
                          O CH1 0mA  0ms    0ms   600000ns 180us RATE   
                          O CH2 0mA  0ms    0ms   600000ns 180us RATE
                  
                  

                  I basically need to change parameters in the last two lines of the file. I can access a particular line but don't know how to split the Line and get the Value. Here parameters are presented as a list of space-separated variables.

                  p.s.
                  The description is formatted as ASCII text. Multiple space characters are collapsed into one. Comments are enclosed in `` and replaced with space characters. A single backtick ` starts a comment that continues to the end of the line.

                  J Offline
                  J Offline
                  JonB
                  wrote on 23 Jan 2020, 11:28 last edited by JonB
                  #8

                  @viniltc said in Modify a .txt file:

                  I can access a particular line but don't know how to split the Line and get the Value.

                  One of the https://doc.qt.io/qt-5/qstring.html#split overloads. For (multiple) whitespace probably line.split(QRegularExpression("\\s+")). Or spaces only, I think, line.split(' ', QString::SkipEmptyParts). If guarantee only one space separator (you say this, but files doesn't look like that), line.split(' ').

                  (Of course, if you actually need to parse the file to deal correctly with your backtick comments to find the right line that is another matter.)

                  1 Reply Last reply
                  2
                  • V Offline
                    V Offline
                    viniltc
                    wrote on 23 Jan 2020, 13:37 last edited by viniltc
                    #9

                    @JonB Thanks. That works perfectly.

                    Can someone show me example how to write content back to the file. If I do following change to the line.

                    QString filename = "config_keygrip";
                     QString path = QCoreApplication::applicationDirPath()+"/"+filename+".txt";
                     QFile file(path);
                    
                    if(!file.open(QIODevice::ReadOnly  | QIODevice::Text))
                        {
                            QMessageBox::information(this, "Unable to open file for read", file.errorString());
                            return;
                        }
                    
                        else
                        {
                            QTextStream in(&file);
                    
                            while(!in.atEnd())
                            {
                                QString line = in.readLine();
                                QString trackName("O CH1");
                                int pos = line.indexOf(trackName);
                                if (pos >= 0)
                                {
                                    QStringList list = line.split(' ', QString::SkipEmptyParts);
                                    QString currVal = QString::number(ui->verticalSlider->value());
                                    list[3] = currVal;       
                                }
                               
                            }
                    
                            file.close();
                        }
                    
                    
                    J 1 Reply Last reply 23 Jan 2020, 13:39
                    0
                    • V viniltc
                      23 Jan 2020, 13:37

                      @JonB Thanks. That works perfectly.

                      Can someone show me example how to write content back to the file. If I do following change to the line.

                      QString filename = "config_keygrip";
                       QString path = QCoreApplication::applicationDirPath()+"/"+filename+".txt";
                       QFile file(path);
                      
                      if(!file.open(QIODevice::ReadOnly  | QIODevice::Text))
                          {
                              QMessageBox::information(this, "Unable to open file for read", file.errorString());
                              return;
                          }
                      
                          else
                          {
                              QTextStream in(&file);
                      
                              while(!in.atEnd())
                              {
                                  QString line = in.readLine();
                                  QString trackName("O CH1");
                                  int pos = line.indexOf(trackName);
                                  if (pos >= 0)
                                  {
                                      QStringList list = line.split(' ', QString::SkipEmptyParts);
                                      QString currVal = QString::number(ui->verticalSlider->value());
                                      list[3] = currVal;       
                                  }
                                 
                              }
                      
                              file.close();
                          }
                      
                      
                      J Offline
                      J Offline
                      jsulm
                      Lifetime Qt Champion
                      wrote on 23 Jan 2020, 13:39 last edited by
                      #10

                      @viniltc https://doc.qt.io/qt-5/qfile.html has examples how to write into a file. Just iterate over your QStringList and write each entry into the file.

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

                      V 1 Reply Last reply 23 Jan 2020, 17:08
                      5
                      • F Fuel 0
                        23 Jan 2020, 10:34

                        Maybe not a clean Way, but you can split the Line and get the Value. Save the Value in a Variable and bind it to your Silder. Make a Save Button. When you save then build a new String and replace the complete Line. When you read the Line maybe you can count the Lines, so you know in which Line you have to replace everything. For that you need the complete File in a String or something. To write everything back is as easy as you read the File. Just overwrite everything.

                        Thats the first Thing i would try, but perhaps someone has a better Solution.

                        V Offline
                        V Offline
                        viniltc
                        wrote on 23 Jan 2020, 15:09 last edited by viniltc
                        #11
                        This post is deleted!
                        1 Reply Last reply
                        0
                        • J jsulm
                          23 Jan 2020, 13:39

                          @viniltc https://doc.qt.io/qt-5/qfile.html has examples how to write into a file. Just iterate over your QStringList and write each entry into the file.

                          V Offline
                          V Offline
                          viniltc
                          wrote on 23 Jan 2020, 17:08 last edited by
                          #12

                          @jsulm
                          I'm a bit stuck at this moment.
                          By this, I can change the parameter in those particular line.

                          QString filename = "config_keygrip";
                           QString path = QCoreApplication::applicationDirPath()+"/"+filename+".txt";
                           QFile file(path);
                          
                          if(!file.open(QIODevice::ReadOnly  | QIODevice::Text))
                              {
                                  QMessageBox::information(this, "Unable to open file for read", file.errorString());
                                  return;
                              }
                          
                              else
                              {
                                  QTextStream in(&file);
                          
                                  while(!in.atEnd())
                                  {
                                      QString line = in.readLine();
                                      QString trackName("O CH1");
                                      int pos = line.indexOf(trackName);
                                      if (pos >= 0)
                                      {
                                          QStringList list = line.split(' ', QString::SkipEmptyParts);
                                          QString currVal = QString::number(ui->verticalSlider->value());
                                          list[3] = currVal;       
                                      }
                                     
                                  }
                          
                                  file.close();
                              }
                          
                          

                          But dont know where to open file for writing. Can someone show me how to do it?

                          J J 2 Replies Last reply 24 Jan 2020, 06:14
                          0
                          • V viniltc
                            23 Jan 2020, 17:08

                            @jsulm
                            I'm a bit stuck at this moment.
                            By this, I can change the parameter in those particular line.

                            QString filename = "config_keygrip";
                             QString path = QCoreApplication::applicationDirPath()+"/"+filename+".txt";
                             QFile file(path);
                            
                            if(!file.open(QIODevice::ReadOnly  | QIODevice::Text))
                                {
                                    QMessageBox::information(this, "Unable to open file for read", file.errorString());
                                    return;
                                }
                            
                                else
                                {
                                    QTextStream in(&file);
                            
                                    while(!in.atEnd())
                                    {
                                        QString line = in.readLine();
                                        QString trackName("O CH1");
                                        int pos = line.indexOf(trackName);
                                        if (pos >= 0)
                                        {
                                            QStringList list = line.split(' ', QString::SkipEmptyParts);
                                            QString currVal = QString::number(ui->verticalSlider->value());
                                            list[3] = currVal;       
                                        }
                                       
                                    }
                            
                                    file.close();
                                }
                            
                            

                            But dont know where to open file for writing. Can someone show me how to do it?

                            J Offline
                            J Offline
                            jsulm
                            Lifetime Qt Champion
                            wrote on 24 Jan 2020, 06:14 last edited by
                            #13

                            @viniltc said in Modify a .txt file:

                            But dont know where to open file for writing

                            You should know when you want to write back.
                            For example after you call

                            file.close();
                            

                            if you want write back just after changing the line.

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

                            1 Reply Last reply
                            4
                            • V viniltc
                              23 Jan 2020, 17:08

                              @jsulm
                              I'm a bit stuck at this moment.
                              By this, I can change the parameter in those particular line.

                              QString filename = "config_keygrip";
                               QString path = QCoreApplication::applicationDirPath()+"/"+filename+".txt";
                               QFile file(path);
                              
                              if(!file.open(QIODevice::ReadOnly  | QIODevice::Text))
                                  {
                                      QMessageBox::information(this, "Unable to open file for read", file.errorString());
                                      return;
                                  }
                              
                                  else
                                  {
                                      QTextStream in(&file);
                              
                                      while(!in.atEnd())
                                      {
                                          QString line = in.readLine();
                                          QString trackName("O CH1");
                                          int pos = line.indexOf(trackName);
                                          if (pos >= 0)
                                          {
                                              QStringList list = line.split(' ', QString::SkipEmptyParts);
                                              QString currVal = QString::number(ui->verticalSlider->value());
                                              list[3] = currVal;       
                                          }
                                         
                                      }
                              
                                      file.close();
                                  }
                              
                              

                              But dont know where to open file for writing. Can someone show me how to do it?

                              J Offline
                              J Offline
                              JonB
                              wrote on 24 Jan 2020, 08:31 last edited by
                              #14

                              @viniltc
                              I'm not going to write code for you, but I will tell you what you need to do where:

                              First, after list[3] = currVal; you now need to reconstruct the new line from list. Hint: since you used QString::split() to split it into a QStringList look at QStringList::join().

                              And second, as I wrote earlier, you have to decide whether you wish to output to temporary file as you go along reading or whether you want to hold the whole new output in memory and write back to original file at the end:

                              • If write as go along: Open the temporary file for write immediately after you have opened the original file for read. Output a line at a time from your read loop. Close output file after closing input file, and then rename temporary output file to original input file.

                              • If write at end: Store the output lines in memory from inside the read loop (e.g. into a QStringList). After you have closed input file from reading it, re-open it for overwrite. Send all lines from memory string list to file. Close file.

                              1 Reply Last reply
                              3
                              • V Offline
                                V Offline
                                viniltc
                                wrote on 30 Jan 2020, 14:55 last edited by
                                #15

                                @JonB Thanks a lot for your feedback :)

                                1 Reply Last reply
                                0

                                10/15

                                23 Jan 2020, 13:39

                                • Login

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