PDA

View Full Version : Editing the file using the seek operations



grsandeep85
22nd March 2010, 10:46
Hi All,

how do i edit the particular line content in a file.txt using seek operations, any code snippet will be useful.

JohannesMunk
22nd March 2010, 12:46
I don't think its possible/sensible to directly edit a text file. Because the length of the line will probably have changed, and thus you will overwrite parts of the next line or have some left-over characters... There is no way of inserting data into a file, just overwriting or appending.. So whenever you want to really insert something, you need to rewrite the file entirely.

That's why text files, that you want to change, should be small enough, that rewriting them entirely, is not a problem.



QFile* f = new QFile("test.txt");
if (f->open(QIODevice::ReadOnly | QIODevice::Text))
{
QTextStream* ts = new QTextStream(f);
QStringList lines = ts->readAll().split("\n");
...
delete ts;
f->close();
}
delete f;


Writing works the same way, but with WriteOnly, write(lines.join("\n")) .. If you don't need all the lines at once.. you can read and write the text-file line by line using two QFile instances and readLine and write.

What do you want to do? Update some line separated values? Have a look at QSettings:


QSettings settings("/home/petra/misc/myapp.ini", QSettings::IniFormat);

HIH

Johannes

grsandeep85
23rd March 2010, 04:26
Hi,

Thanks for the reply Johannes, Actually I have made a application that consists of 4 lineEdits such as number, x, y , z the user will input the values to lineEdits and these values should be stored in a file.txt and also the user can change the values and these corresponding values has to be updated in the values the file looks like this

# X Y Z
5.000, 6.005, 8.340
45.220, 987.000, 64.000
21.000, 88.980, 73.000

and so on

how to eidt the values if user wants to change and here is the code snippet for accept the values from file then store




void DatumForm::writefile()
{
QStringList lines;
QString line;
QFile file ( datum.txt );
line.append( xdatumlineEdit->text() );
line.append("," );
line.append( ydatumlineEdit->text() );
line.append("," );
line.append( zdatumlineEdit->text() );
lines += line;
if ( file.open( QIODevice::ReadWrite | QIODevice::Append) )
{
QTextStream stream( &file );
for ( QStringList::Iterator it = lines.begin(); it != lines.end(); ++it )
stream << *it << "\n";
file.close();
}
}

void DatumForm::readfile()
{
QString resulttemp;
QStringList lines;
QString line;
int count = -1;
bool ok;
resulttemp = datumnolineEdit->text();
int linenumber = resulttemp.toInt(&ok, 10);

QFile file(datum.txt );
if ( file.open( QIODevice::ReadWrite ) )
{
QTextStream stream( &file );

while ( !stream.atEnd() )
{
count += 1;
line = stream.readLine( );

if(linenumber == count)
{
resulttemp = line;
datumlines = resulttemp.split(",");

Xdatum_Val = datumlines[0].toDouble();
xdatcountlineEdit->setText(QString::number( Xdatum_Val, 'f', 3) );


Ydatum_Val = datumlines[1].toDouble();
ydatcountlineEdit->setText(QString::number( Ydatum_Val, 'f', 3) );


Zdatum_Val = datumlines[2].toDouble();
zdatcountlineEdit->setText(QString::number( Zdatum_Val, 'f', 3) );


}
}
file.close();
}
}



HOW TO PROCEED WITH THIS? THE USER CAN READ OR WRITE THE FILE.....

JohannesMunk
23rd March 2010, 10:43
You didn't quite read my reply, did you? No ReadWrite for TextFiles!!

What you need to do is read everything, change your line and then rewrite everything.

Why don't you load the data at program begin, store it in a list for the user to to edit and append, and then write to file, when the user saves/exits?



struct XYZTriple {
double x;
double y;
double z;
}

// maybe as private member of your class:
class DatumForm : ..
{
private:
QList<XYZTriple> data;
int oldindex;
}

void DatumForm::readfile()
{
QFile file("datum.txt");
if (file.open( QIODevice::ReadOnly | QIODevice::QIODevice::Text))
{
QTextStream stream( &file );
while ( !stream.atEnd() )
{
line = stream.readLine( );
datumlines = line.split(",");
if (datumlines.length() == 3) {
XYZTriple datum;
datum.x = datumlines[0].toDouble();
datum.y = datumlines[1].toDouble();
datum.z = datumlines[2].toDouble();
data.append(datum);
} else {
// error in line..
}
}
file.close();
}
}

void DatumForm::writefile()
{
QFile file("datum.txt");
if (file.open( QIODevice::WriteOnly | QIODevice::QIODevice::Text | QIODevice::Truncate))
{
QTextStream stream( &file );
for (int i=0;i<data.length();++i)
{
stream << QString("%1,%2,%3\n").arg(data[i].x,0,'f', 3).arg(data[i].y,0,'f', 3).arg(data[i].z,0,'f', 3);
}
stream.flush();
file.close();
}
}
For your Widgets, don't use simple LineEdits, but QSpinBox and QDoubleSpinBox.

Now you need to make sure, that your lineNumber is in the right range, and if it is beyond => append data.



DatumForm::DatumForm()
{
..
oldindex = 0;
lineNumberSpinBox->setMinimum(1);
}

void DatumForm::lineNumberSpinBoxValueChanged(int i)
{
// save values in array if previous value is valid
if (oldindex > 0)
{
data[oldindex-1].x = xValueDoubleSpinBox->value();
data[oldindex-1].y = yValueDoubleSpinBox->value();
data[oldindex-1].z = zValueDoubleSpinBox->value();
}
// make sure list is big enough:
for (var j=data.length();j<i;++j)
{
// add default values..
XYZTriple datum = {0.0,0.0,0.0};
data.append(datum);
}
// show the values
xValueDoubleSpinBox->setValue(data[i-1].x);
yValueDoubleSpinBox->setValue(data[i-1].y);
zValueDoubleSpinBox->setValue(data[i-1].z);
// save oldindex
oldindex = i;
}
You could also restrict the lineNumber to the valid ranage with QSpinBox::setRange(1,data.length()) and have an additional append-button.

Now: Good luck with your project!

BTW: Code is as is :-> There are probably several typos in there...

Johannes

girishgowda
24th March 2010, 04:30
Sandeep,

My understanding is that files will have sequential data (unless and until you use some specific file formats ex csv etc and have specific drivers to support those - if any).

The functionality you want is to edit a specific position of the file. In this case you will need to have some place holders which will tell you which data was editted.
If your data is of fixed length then you can try to overcome the issues mentioned in the post above - by calculating the line eddited and the possible place holder for that data.

Try for some type of data structure to read your file and let the user edit the the values through some UI - which updates your data structure.
Then the data structure should be flushed into the file again - once user editing is completed.
The data structure would have to be a mXn array.
Your code above can be re-framed into this.

Regards
Girish