How to write something at a specific line of a text file?



  • I have a lineedit and a combobox..
    What i want to do is to write the text of the lineedit with the text of the combobox to a certain line on the text file..

    For example:
    My lineedit text = Hi, my name is:
    and the combobox have the options of : Alex, Leon, Bono

    For now i choose Leon.. So when i run the program i want the text file at the line 3 says:
    @Hi, my name is:Leon@

    How can i do this?

    P.S I know how to take a text from a combobox

    @QString combo;
    combo=ui->comboBox->currentText();@

    P.S 2 I know how to work with the command "sed" but i think this isn't the right option


  • Moderators

    Certainly there is always the brute force method with reading and writing the whole file.
    I have not come up with a better solution yet, but I am wondering if "QTextDocument":http://doc.qt.nokia.com/4.7/qtextdocument.html#findBlock is of any help.

    [EDIT: fixed link, Volker]



  • there must be way just to write to the line and not reading and writing the whole file.

    i have seen this -> "fseek":http://www.cplusplus.com/reference/clibrary/cstdio/fseek/ but it doesn't really work for me.. Here is what i do but i have the error of The program has unexpectedly finished.
    @FILE * pFile;
    pFile = fopen ( "/home/$USER/Desktop/document" , "w" );
    fputs ( "This is an apple." , pFile );
    fseek ( pFile , 9 , SEEK_SET );
    fputs ( " sam" , pFile );
    fclose ( pFile );@

    Where "This is an apple." will be what i want.. I know how to do it..
    And i think that where it says 9 it means the line 9? I am not sure..

    I am using Ubuntu


  • Moderators

    No, fseek and ftell are refering to file positions. The main problem you are facing is the line length.
    Since punch cards are no longer up-to-date, programmers have to fight with the problem.
    You need to find the line by reading through the file line by line. In your case 2 lines until you are at the start of line 3. But if the line contains only "sam" and you like to write "samantha", you are gone. You have to have a line which is long enough, let's assume 80 characters, than you have overwrite the whole line. If the line you like to overwrite is shorter the brute force method is the only possibility.



  • Ok i found i way with the "sed" command. And it works nice to me :)
    @ char sedi[150]="sed -i '4 d' /home/$USER/.config/Program/Settings; sed -i "4i\";
    QString outpout_name=ui->avi_outpout->text().toUtf8();
    const char *outpout_name2= outpout_name.toLatin1();
    strcat(sedi, outpout_name2);
    QString file_extension=ui->avi_to_file_extension->currentText();
    const char *file_extension_2 = file_extension.toAscii().data();
    strcat(sedi, file_extension_2);
    char sedi2[450]="\n" /home/$USER/.config/Program/Settings";
    strcat(sedi, sedi2);
    if(system(sedi))
    cout << "FATAL ERROR: Couldn't write to ~/.config/Program/Settings, which is essential for the functionality of the program.\nPlease check the file's permissions.\n";
    }@


  • Moderators

    Good to know that your problem is solved.
    I am more on Windows. Most of the linux goodies are some kind of strange to me ;-)

    Have fun.



  • I would be quite suprised if sed didn't essentially do the same: read, modify, write. Not sure how much you gained there, though it is certainly possible that sed uses a more efficient way to access the file system than you'd be able to do with Qt.


  • Moderators

    [quote author="Andre" date="1307113294"]I would be quite suprised if sed didn't essentially do the same: read, modify, write. Not sure how much you gained there, though it is certainly possible that sed uses a more efficient way to access the file system than you'd be able to do with Qt. [/quote]

    You are right from that perspective there is not gained a lot. Leon's method would loose in performance when a couple of lines have to be changed.


  • Moderators

    I really am impressed with that piece of code!

    It managed to avoid doing the bit of work required to read/modify/write the file by having somebody else do the same thing. That not only made the program a bit harder to read (who knows sed these days?), it also introduced a buffer overflow. That is something that is really hard to do when using QByteArray or QString, but that was avoided in favor of fixed sized buffers and strcat (together with user provided input and without range checks). I had really thought that kind of error was left behind in the C world.

    Then this sed invocation is rather interesting. It assumes a very fixed file structure and looks rather fragile in the face of changes to it. The code also assumes that there is a sed in the path of the system (which generally is not the case on windows) and even requires the gnu-version of sed (not available on most non-Linux unixes out there). That might be OK for the use-case, but adds some probably undocumented assumptions about the execution environment and makes the application less portable without any real need.

    Finally the string conversions are horrible: Assuming avi_outpout->text() returns a QString this is converted from utf16 to utf8 and straight back. Then that variable is converted to latin1 encoded outpout_name2... maybe loosing characters in the process. The file extension it assumed to be ASCII (which might or might not be true, depending on the program and how the extensions can be configured). This mixture of encodings (ASCII, Latin1 and the encoding the source was saved as) is concatenated into one string and the system is expected to execute that, independent of which encoding the system might actually be using. There is a toLocal8Bit() method on QString for a reason.

    The user input is of course not validated either. "Bobby Tables":http://xkcd.com/327/ is lurking in the bushes.

    Really, I am truly impressed by that code.


Log in to reply
 

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