Qt delete a line from file - c++

I am reading a QFile with QTextStream.
QFile file("example.txt");
QTextStream in(&file);
QString line = in.readLine();
while (!line.isNull()) {
if(line.contains("DELETE"))
{
// delete line
}
line = in.readLine();
}
Is there a way to delete a line ?

You can open your file, read the contents, modify the contents, and then write them back to the file. Here is one way to do this:
QFile f("myfile.txt");
if(f.open(QIODevice::ReadWrite | QIODevice::Text))
{
QString s;
QTextStream t(&f);
while(!t.atEnd())
{
QString line = t.readLine();
if(!line.contains("DELETE"))
s.append(line + "\n");
}
f.resize(0);
t << s;
f.close();
}

As far as i know, it's not simple as that. The best solution i can think about is to the read the whole file line-by-line, push every line into a QVector, then modify the container's elements as you want, then push it back to the file.

delete a line means shift of all the rest backward.
simplest way is to write back lines in new place after first deletion.
Using temp file, and rename it to the original if success, is the safest way.
but you never write more then you read so it suppose to be OK to work on the same file.
you need to keep read pos and write pos.
it should be something like this: (based on the original code)
QFile file("example.txt");
QTextStream in(&file,QIODevice::ReadWrite);
QString line = in.readLine();
qint64 rpos,wpos=0;
bool shift = false;
while (!line.isNull()) {
rpos = in.pos();
if(!line.contains("DELETE"))
{
if(shift){
in.seek(wpos);
in<<line<<endl;
wpos = in.pos();
in.seek(rpos);
} else{
wpos = rpos;
}
}else{
shift = true;
}
in.seek(rpos);
line = in.readLine();
}
file.resize(wpos);

Related

Add string into a text file at a certain string value

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 accomplish this.
but unsure how to add strings under the line,
so once it finds that line
line in question found stript blablabla
// under this line in the file I want to add certain things but unsure how to approach this.

how to read only one line in a text file which has particular word using Qt

I am reading a .txt file, I want to read only 1 line with particular word. I'm using Qt Creator.
How can I achieve this?
This is my code so far:
QFile file("/home/a1.txt");
if (!file.open(QFile::ReadOnly | QFile::Text)) {
QMessageBox::warning(this,"title","file not open");
}
QTextStream in(&file);
QString text = in.readAll();
ui->plainTextEdit->setPlainText(text);
file.close();
If you want to search all lines for a specific word you can do this
QFile file("/home/a1.txt");
if (!file.open(QFile::ReadOnly | QFile::Text)) {
QMessageBox::warning(this,"title","file not open");
}
QTextStream in(&file);
QString text;
while (!in.atEnd()) {
text = in.readLine();
if (text.contains(/*Search her for the word you want.*/))
break;
}
ui->plainTextEdit->setPlainText(text);
file.close();
So you loop through all lines. And in every line you check if the word exist. If yes you can stop searching and leave the loop.
I hope this helps!

Better way to use QDomDocument data as text

I am a newbie, I am creating a XML file in which I need to give CRC value to cross check on server. For this I need QDomDocument data as text. For this I am first creating XML file with fake CRC value. Then I open it with QFile and read all data. Then I split data and calculate data CRC. Now I have to rewrite whole file again. I know it is the worst idea ever to write same file twice but as I am a newbie, I don't know how to do it in better style. Here is my code:-
QDomElement docElem = doc.documentElement();
QFile xmlfile(filename);
if(!xmlfile.open(QIODevice::ReadWrite | QIODevice::Text))
{
qDebug("Can not open file device.");
}
xmlfile.resize(0);
QXmlStreamWriter xw;
xw.setDevice(&xmlfile); //set file to XML writer
xw.setAutoFormatting(true);
xw.setAutoFormattingIndent(4);
xw.writeStartDocument();
xw.writeStartElement(fileID); //fileID as the start element
if(docElem.hasAttributes())
{
xw.writeAttribute("xmlns:xs",docElem.attribute("xmlns:xs"));
xw.writeAttribute("xmlns",docElem.attribute("xmlns"));
}
xw.writeTextElement("Frame_Start_ID","STX");
xw.writeTextElement("Frame_Length","1234");
xw.writeTextElement("Source_Device_Id","CDIS_PIS ");
xw.writeTextElement("Destination_Device_Id","DDNS-SERVER ");
xw.writeTextElement("Frame_Code","I");
xw.writeStartElement("Frame_Data");
//inside frame data
xw.writeTextElement("File_Number","1");
xw.writeTextElement("File_Name","Event");
for(int j=0;j<logFields.count();j++)
{
xw.writeTextElement(logFields.at(j),logData.at(j));
}
xw.writeEndElement();
xw.writeTextElement("CRC","14405904");
xw.writeTextElement("Frame_End_Id","ETX");
xw.writeEndDocument();
xmlfile.flush();
xmlfile.close();
QFile xmlfyle(filename);
xmlfyle.open(QIODevice::ReadWrite | QIODevice::Text);
QString content = (QString)xmlfyle.readAll();
QStringList list1 = content.split("<CRC>");
qDebug() << "Split value = " << list1.at(0);
QByteArray crc_new = crc_o.crc_generate_modbus((unsigned char*)list1.at(0).data(),list1.at(0).size());
xmlfyle.resize(0);
QXmlStreamWriter xw_new;
xw_new.setDevice(&xmlfyle); //set file to XML writer
xw_new.setAutoFormatting(true);
xw_new.setAutoFormattingIndent(4);
xw_new.writeStartDocument();
xw_new.writeStartElement(fileID); //fileID as the start element
if(docElem.hasAttributes())
{
xw_new.writeAttribute("xmlns:xs",docElem.attribute("xmlns:xs"));
xw_new.writeAttribute("xmlns",docElem.attribute("xmlns"));
}
xw_new.writeTextElement("Frame_Start_ID","STX");
xw_new.writeTextElement("Frame_Length","1234");
xw_new.writeTextElement("Source_Device_Id","CDIS_PIS ");
xw_new.writeTextElement("Destination_Device_Id","DDNS-SERVER ");
xw_new.writeTextElement("Frame_Code","I");
xw_new.writeStartElement("Frame_Data");
xw_new.writeTextElement("File_Number","1");
xw_new.writeTextElement("File_Name","Event");
for(int j=0;j<logFields.count();j++)
{
xw_new.writeTextElement(logFields.at(j),logData.at(j));
}
xw_new.writeEndElement();
char tab[10];
sprintf(tab,"%d",crc_new.data());
xw_new.writeTextElement("CRC",QString::fromUtf8(tab));
xw_new.writeTextElement("Frame_End_Id","ETX");
xw_new.writeEndDocument();
xmlfyle.flush();
xmlfyle.close();
can anyone suggest me what could be a better way to do this.Thanks
One version of QXmlStreamWriter constructor accepts a QByteArray and writes into the array instead of an output file.
QXmlStreamWriter Class
So what you can do is; using QXmlStreamWriter, prepare data for your XML in a QByteArray, do whatever you need to do with the CRC inside this data; and when everything is done, write this QByteArray to the output file.

QstringList to Qstring conversion issues

I am working on VS2015 with qt framework. In my source code, I have a function for printing in the GUI screen.
This function is called each time something needs to be printed.
It goes like this.
void Trial::Print_MessageBox(QString string)
{
ui.MessagesScreen->appendPlainText(string);
Cursor_Messagebox.movePosition(QTextCursor::End);
ui.MessagesScreen->setTextCursor(Cursor_Messagebox);
ui.MessagesScreen->ensureCursorVisible();
}
// Output in MessageBox
void Trial::Print_MessageBox(QFlags<QNetworkInterface::InterfaceFlag> flags)
{
QString str = QString("Flag %1").arg(flags);
ui.MessagesScreen->appendPlainText(str);
}
The above function has no problems and running well.
Now I am trying to read a text file. This has set of values in no order or size. An example for this:
231, 54, 4 \n
47777, 2211, 676, 9790, 34236, 7898\n
1, 3\n
Objective is to convert these into integers (line by line) and print them in the GUI and also send them (line by line) to other system. So I tried to do it with the following.
void Trial::ReadFile_Data()
{
QFile file("input.txt");
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
{
Print_MessageBox("Error in reading File");
return;
}
QTextStream in(&file);
while (!in.atEnd())
{
QString line = in.readLine();
Print_MessageBox(line);
int conv = line.toInt();
QString str = QString("%1 %2").arg("Values are: ").arg(conv);
Print_MessageBox(str);
QStringList fields = line.split(",");
}
file.close();
}
When I print the "line", it is just printing the same values as in the file. When I do the conversion and printing, I get an error (which is expected) Now I try to remove "," with the help of split then I get QstringList which I cannot use as I have the Qstring function to print(this cant be changed)
I am not getting any pointers from here. Please help me out as this is bugging me since long time.
Just simple...
QStringList::const_iterator constIterator;
for (constIterator = fonts.constBegin(); constIterator != fonts.constEnd();
++constIterator) {
cout << (*constIterator).toLocal8Bit().constData() << endl;
}
where fonts is your QStringlist
Your question reduces to "How do I iterate over a QStringList".
Like this:
// C++11
for (auto field : fields) Print_messageBox(field);
// C++98
foreach (QString field, fields) Print_messageBox(field);
See here for information about how foreach a.k.a Q_FOREACH was implemented.

Comparing QByteArrays

I am making a file editor in Qt C++.
I noticed that when I save the source file with notepad on Windows it substitutes 0x0D + 0x0A for every new line (ANSI encoding default).
If I get the data from a QTextEdit and convert that to a QByteArray it substitutes line endings with 0x0A.
Now my main problem is that I don't know how to either filter out these line endings or make it so that QFile reads files different.
I just want a way of comparing whether there are changes that need to be saved.
The code is below:
bool QFileTab::needSave()
{
QFile file1 ( this->filePath );
file1.open(QIODevice::ReadOnly);
QByteArray data1 ( file1.readAll() );
QByteArray data2 ( this->body.toPlainText().toLocal8Bit() );
file1.close();
return !IOHandler::compare(data1, data2);
}
void IOHandler::read(QFileTab *tab)
{
QFile temp (tab->filePath);
if(temp.open(QIODevice::ReadOnly | QIODevice::Text))
{
QString data(temp.readAll());
tab->data = data;
temp.close();
} else tab->data = QString("The file could not be read.");
tab->doUpdate();
}
bool IOHandler::compare(QByteArray data1, QByteArray data2)
{
return data1 == data2;
}
I want to be able to read, compare and write to files on Windows and Linux.