Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Add text under line found in a text file.



  • i have created this code here

    void elfenliedtopfan5_wep_adder_res::zonefilesetup(QString file)
    {
        QFile inputFile(file);
        if (inputFile.open(QIODevice::ReadOnly))
        {
           QTextStream in(&inputFile);
           while (!in.atEnd())
           {
              QString line = in.readLine();
              if(line.contains("scriptparsetree,scripts/zm/" + elfenliedtopfan5settings->value("ModName").toString() + ".csc"))
              {
                  qDebug() << "We Hit" << line;
                  break;
              }
              else
              {
                  qDebug() << "We Did Not Hit" << line;
              }
           }
           inputFile.close();
        }
    }
    
    and what i wanting to do is add text under the line we hit so once found add text to file under that line 
    
    the file contents are 
    
    

    class,zm_mod_level
    group,modtools

    xmodel,skybox_default_day
    material,luts_t7_default

    // BSP
    col_map,maps/zm/zm_elfenlied_v2.d3dbsp
    gfx_map,maps/zm/zm_elfenlied_v2.d3dbsp

    // Audio
    sound,zm_elfenlied_v2

    scriptparsetree,scripts/zm/zm_elfenlied_v2.gsc
    scriptparsetree,scripts/zm/zm_elfenlied_v2.csc

    // JARIK ELFENLIED LUA SETUP
    scriptparsetree,scripts/zm/_zm_elfen_test.csc
    scriptparsetree,scripts/zm/_zm_elfen_test.gsc
    rawfile,ui/uieditor/menus/hud/T7Hud_zm_custom.lua
    rawfile,ui/uieditor/widgets/elfenlied/zmElfenliedAmmoContainer.lua
    rawfile,ui/uieditor/widgets/elfenlied/zmElfenLiedDefaultAmmo.lua
    rawfile,ui/uieditor/widgets/elfenlied/zmElfenliedSpecialAmmo.lua
    rawfile,ui/uieditor/widgets/elfenlied/zmElfenliedAmmoClipContainer.lua
    rawfile,ui/uieditor/widgets/elfenlied/zmElfenliedGrenades.lua
    image,elfenlied_special_ammo_stock_box
    image,elfenlied_special_ammo_box
    image,elfenlied_special_zombies_left_box
    image,elfenlied_special_ammo_stock_box_red
    image,elfenlied_special_ammo_box_red
    image,elfenlied_special_zombies_left_box_red
    image,elfenlied_anime_girl
    image,gun_backing_main
    // END

    // ELFENLIED WEAPON HUDS.
    image,uie_elfenlied_icon_p90_iw8_upg
    image,uie_elfenlied_icon_pistol_standard

    //ELFENLIEDTOPFAN5 MW19 PORTS
    //MYSTERY BOX
    stringtable,gamedata/weapons/zm/zm_levelcommon_weapons.csv

    //WEAPONS
    weapon,renetti
    weapon,p90_iw8
    weapon,p90_iw8_upg
    //END

    weapon,bo4_gks
    weapon,bo4_gks_upgraded
    weapon,aug_t8
    weapon,aug_t8_upg
    weapon,mp7_iw8
    weapon,mp7_iw8_upg

    
    

    the line i have found is
    scriptparsetree,scripts/zm/zm_elfenlied_v2.csc

    so want to find this line and under this line add more values but unsure how to accoumplish this.

    thanks in advance elfenliedtopfan5



  • @elfenliedtopfan5

    You open your file only in ReadOnly mode. You need ReadWrite to write to file.

    QTextStream / QFileis not meant to insert content somewhere between existing content of a file. You can append to its end or re-write the whole file with the new content. So read the whole file into a buffer or some tmp file, find your position and then write the new content again.



  • Thank you for reply i will look into it once i finish work sorry i come in form c# so still trying to learn c++ and QT watched and took part in a lot of online courses but none really go in-depth on how to parse and add text at certain parts so its still a learning curve for me but i will have a look if i manage to fix it i mark your reply as answer thanks for a fast response ,

    elfenliedtopfan5



  • @elfenliedtopfan5

    FYI: Even in C# you have to re-write the whole file.

    Because you cant "move" content of a written file, what you need to do, if you want to add something to the middle of the file. Appending to the end of a file, is no big deal and a quite simple task.



  • Yeah but its a lot more different in syntax at least with c#

    but i managed to load evreything into a string list,

    would that be any good just trying to find a way of getting the string i looking for apprend the new string at the index of that string and save the qstringlist back to the file.

    got this

        QStringList stringList;
        QFile textfile(file);
        if(textfile.open(QIODevice::ReadWrite))
        {
            //... (open the file for reading, etc.)
            QTextStream textStream(&textfile);
            while (true)
            {
                QString line = textStream.readLine();
                qDebug() << line;
                if (line.isNull())
                    break;
                else
                    stringList.append(line);
            }
        }
    
    
        if(stringList.contains("scriptparsetree,scripts/zm/" + elfenliedtopfan5settings->value("ModName").toString() + ".csc"))
        {
            stringList.indexOf("scriptparsetree,scripts/zm/" + elfenliedtopfan5settings->value("ModName").toString() + ".csc");
            stringList.append("tESTsTRING");
    
            qDebug() << stringList;
        }
        else
        {
    
        }
    


  • @elfenliedtopfan5
    Forget opening for QIODevice::ReadWrite.

    If you had said you wanted to add a new sting only to the end of the file, that can be done quickly.

    But you specifically state you want to insert a new string into the middle of the file. To do that, you must read the whole file once through, make your change in memory, and write the whole of the new file back:

    1. Open file for read.
    2. Read all lines into QStringList.
    3. Close the file.
    4. Make a change in memory, like inserting a string somewhere in the list.
    5. Open file for write.
    6. Write all lines from QStringList.
    7. Close the file.

    You could do it via QIODevice::ReadWrite, but it probably won't be any faster, you still have to follow the principle of re-writing all the lines at least from the changed one onward. You cannot "insert with shift rest" into a file. The two separate read and write-back phases in my steps are the way you'll see most people do it.



  • That is great thank you the only part of that i dont understand is how to make the change in memory like inserting the string in the place i want its quite annoying to do it i tried but cant seem to get it to show up would it be index of ? i would have to use to get it to work of foreach and go though all lines once line is found add to qlist there and continue to read file

    then like you said there save it back out with it already in the correct place sorry kinda new to c++ learning its just a little confusing sorry to be a pain.



  • @elfenliedtopfan5
    Now I give you a separate reply with a different approach. From looking at the examples you give of what you want to do.

    You seem to be doing: "if I come across a line containing such and such a string, I want to put a new string immediately after it; or I want to change something in it and write it back it out". It's hard to be sure, I don't think your example code is right for that anyway.

    If that's the case, consider the following:

    1. Open file for read.
    2. Open a new, non-existent file for write.
    3. Read one line at a time from input file, normally copying that line to output file.
    4. If you want to change a line, or insert a new one here, do so as you go.
    5. Close both files.
    6. Rename the newly created file back to the original file.

    This will save a lot of memory on any big files!



  • @elfenliedtopfan5

    If you don't want to use @JonB 's second approach, consider using an iterator to insert your stuff into your QStringList.
    Note: append() will only insert at the end.

    https://doc.qt.io/qt-5/qstringlist.html#QMutableStringListIterator-typedef



  • @JonB well i have tryied this it creates the file file,

    and does take the file line by line but it not putting anything into the file created

        QFile zonefile(file);
        
            QFile zonefiletemp(file+"temp");
      
      
            // original read ->
        
            if(!zonefile.open(QIODevice::ReadOnly))
        
            {
        
                return;
        
            }
        
            else
        
            {
        
                QTextStream read(&zonefile);
        
                while(!read.atEnd())
        
                {
        
                    QString lines = read.readLine();
        
        
        
                        QTextStream readto(&zonefiletemp);
        
        
        
                        QString filename = file + "temp";
        
                        QFile newfile(filename);
        
        
        
                        if(newfile.open(QIODevice::WriteOnly))
        
                        {
        
                            QTextStream readto(&newfile);
        
                            {
        
                                readto << lines << Qt::endl;
        
                                qDebug() << lines;
        
                            }
        
        
        
                        }
        
        
        
                    }
        
                }
        
        
        
                zonefile.close();
        
                zonefiletemp.close();
        
        
        
        
        
            }
        
        t its annoying. 
    but im getting there slowly at the moment im just opying across line by line to the file to get that working then was going to implement the custom string when its done


  • @elfenliedtopfan5
    You are (re-)opening the output file in the loop which reads a line at a time from the input. I numbered the steps you should follow.


Log in to reply