Find last of... and write above.
-
Hello to everyone.
First of all thanks a lot for reading this post and being able to help.I have a .txt, for example:
1. Hello world 2. This world is really big... 3. I love this world.
What I would like is to write a line above the last line which contains "world.
So in this case image that I want to write the line "This forum is amazing".
So the .txt will have to be:1. Hello world 2. This world is really big... 3. This forum is amazing 4. I love this world.
So I have to:
1º first find last word of world.
2º Write above.How can I do that?
Any help?thanks a lot!
-
QFile file(fileName); if (file.open(QIODevice::ReadWrite | QIODevice::Text)) { // read lines QStringList lines; int lastIdx = -1; QTextStream in(&file); for( int i= 0; !in.atEnd(), ++i ) { QString line = in.readLine(); lines << line; if( line.contains("XXX") ) lastIdx = i; } // insert your line lines.insert( lastIdx-1, ... ); //write back to file file.seek(0); file.write( lines.join("\n") ); file.close(); }
You should only use this code if the files aren't too big, since everything is loaded into the memory.
Also i left out some error checking and it's untested, but it should give you an idea. -
Here's a little shorter version, with a lot less allocations:
//insert stuff before line with last occurrence void isblwlo(const QString& file, const QString& what, const QString& stuff) { QFile f(file); if (!f.open(QIODevice::ReadWrite | QIODevice::Text)) return; QByteArray buff = f.readAll(); int pos = buff.lastIndexOf(what); if (pos < 0) return; int endline_pos = buff.lastIndexOf("\n", pos) + 1; buff.insert(endline_pos, stuff + "\n"); f.seek(0); f.write(buff); }
You could trim it down even more by not doing an insert and writing in three parts - up to
endline_pos
,stuff
and afterendline_pos
. Then only one allocation would remain. I'll leave it as an exercise to the reader ;)Same warning applies - don't use for large files.
-
You've got a couple of C++ answers :) If you are looking for QML / Js answer. You can pass your new line into the <line> param and the original text into <txt> param. The code is pretty short and mostly self explanatory. You are dividing the text into an array of lines by using the new line character "\n" and then inserting a new line into the list and putting it back together as one blob of text.
function insertAsSecondLastLine(line,txt) { var arr = !txt ? [] : txt.split("\n") if(arr.length > 0) { var lineNumber = arr.length - 1 arr.splice(lineNumber,0,line); } else { arr.push(line); } return arr.join("\n") }
-
@raven-worx said:
QFile file(fileName); if (file.open(QIODevice::ReadWrite | QIODevice::Text)) { // read lines QStringList lines; int lastIdx = -1; QTextStream in(&file); for( int i= 0; !in.atEnd(), ++i ) { QString line = in.readLine(); lines << line; if( line.contains("XXX") ) lastIdx = i; } // insert your line lines.insert( lastIdx-1, ... ); //write back to file file.seek(0); file.write( lines.join("\n") ); file.close(); }
You should only use this code if the files aren't too big, since everything is loaded into the memory.
Also i left out some error checking and it's untested, but it should give you an idea.Hello my friend.
First of all thanks a lot for answering.I have tried what you say like this:
QString fileName = QFileDialog::getOpenFileName(this,"indicate world","/home","files World (*.world)"); // We use the QFileDialog class to obtein the whole name file that user has choosen. QFile file(fileName); if (file.open(QIODevice::ReadWrite | QIODevice::Text)) { // read lines QStringList lines; int lastIdx = -1; QTextStream in(&file); for( int i= 0; !in.atEnd(); ++i ) { QString line = in.readLine(); lines << line; if( line.contains("world") ) lastIdx = i; } // insert your line lines.insert( lastIdx-1, "writting" ); //write back to file file.seek(0); file.write( lines.join("\n") ); file.close(); }
But it give an error in "file.write( lines.join("\n") );" which is:
cpp:2106: error: no matching function for call to 'QFile::write(QString)'
file.write( lines.join("\n") );
^
Do you know why?Thanks!!
-
@Chris-Kawa said:
Here's a little shorter version, with a lot less allocations:
//insert stuff before line with last occurrence void isblwlo(const QString& file, const QString& what, const QString& stuff) { QFile f(file); if (!f.open(QIODevice::ReadWrite | QIODevice::Text)) return; QByteArray buff = f.readAll(); int pos = buff.lastIndexOf(what); if (pos < 0) return; int endline_pos = buff.lastIndexOf("\n", pos) + 1; buff.insert(endline_pos, stuff + "\n"); f.seek(0); f.write(buff); }
You could trim it down even more by not doing an insert and writing in three parts - up to
endline_pos
,stuff
and afterendline_pos
. Then only one allocation would remain. I'll leave it as an exercise to the reader ;)Same warning applies - don't use for large files.
Thanks a lot, that works!
-
@AlvaroS said:
But it give an error in "file.write( lines.join("\n") );" which is:
cpp:2106: error: no matching function for call to 'QFile::write(QString)'
file.write( lines.join("\n") );
^file.write( lines.join("\n").toUtf8() );
-
@raven-worx Thanks!!!
This thread is solved :)