opening file in Qt - c++

I am trying to read float samples saved in text file. The file appears to be empty, even though it's filled with data. What might be the cause?
QFile file;;
QDir path;
path.setPath("home/kokos/Pobrane/wavreader/libsndfile-1.0.26/examples/ex2/qt_project/rainfilter");
file.setFileName(path.path() + "/samples.txt");
file.open(QIODevice::ReadOnly);
QDataStream in(&file);
while(in.atEnd() == false)
{
in >> samplesBuffer[counter];
counter++;
}

I can't write comments, but I work with qt long time.
Are u sure that file is open? You must open file that:
if(file.open(QIODevice::ReadOnly)){
//some method
}
I think that u need check path name

Related

How to write text to a text file only if not already written

I would like to add text to a text file only if the text doesn't already exist in the text file. My implementation below adds text even if it already exists. How can I fix my implementation to only add new non-existent items?
My implementation so far:
WriteToFile::WriteToFile(QString data)
{
path += "C:/Data.txt";
QFile file(path);
if ( file.open(QFile::Append) )
{
QTextStream in (&file);
QString line;
do {
line = in.readAll();
qDebug() << in.readLine();
if (!line.contains(data)) {
QTextStream stream( &file );
data += "\r\n";
stream << data << endl;
}
} while (!line.isNull());
}
}
You will either have to:
parse the entire file and extract all paths from it or
keep track of all paths written to a file to avoid parsing it again and again
From there is it simple, just create a QSet<QString> writtenSoFar, and for every path, check if the set contains it, if so skip writing, if not, write it and append it to the set. In the first case, you will have to write the parsed paths into the set just to make a single check, wildly inefficient, just like the parsing itself. So better keep track of the paths as you go.
The set is important to give you good lookup performance. It is quite fast, since it is hash based, it is essentially a value-less QHash.

Qt - How to save and load a QVector<QString> into multiple labels?

So I have multiple labels full of text, and I would like to save all of these labels in one go into a QVector<QString>. The Below code is what I have tried and it works but nothing is ever loaded when I load the saved file, I have checked the saved file with notepad and there is stuff in there, so maybe the load option is not working correctly? I'm not sure but help is appreciated. I also ask if you can suggest a better way of doing this if this seems like a bad or horribly inefficient way, again thanks for the help in advance.
The code for saving:
void Tasks::on_pushButton_5_clicked()
{
const int length = 10;
QVector<QString> AllTasks(length);
AllTasks<<ui->label->text()<<ui->label_2->text()<<ui->label_3->text()<<ui->label_4->text()<<
ui->label_5->text()<<ui->label_6->text()<<ui->label_10->text()<<ui->label_11->text()<<
ui->label_12->text()<<ui->label_13->text();
QString fileName = QFileDialog::getSaveFileName(this,tr("Save All Tasks"),"", tr("Tasks(*.tsk);;All Files (*)"));
QFile file(fileName);
if(file.open(QIODevice::WriteOnly)){
QDataStream stream(&file);
stream<<AllTasks;
}
file.close();
}
and the code for loading:
void Tasks::on_pushButton_6_clicked()
{
const int length = 10;
QVector<QString> AllTasks(length);
AllTasks<<ui->label->text()<<ui->label_2->text()<<ui->label_3->text()<<ui->label_4->text()<<
ui->label_5->text()<<ui->label_6->text()<<ui->label_10->text()<<ui->label_11->text()<<
ui->label_12->text()<<ui->label_13->text();
QString fileName = QFileDialog::getOpenFileName(this,tr("Save Tasks"),"", tr("Task(*.tsk);;All Files (*)"));
QFile file(fileName);
if(file.open(QIODevice::ReadOnly)){
QDataStream stream(&file);
stream.setVersion(QDataStream::Qt_4_8);
stream>>AllTasks;
}
file.close();
}
You do this for saving:
AllTasks<<ui->label->text()<<ui->label_2->text()<<ui->label_3->text()<<ui->label_4->text()<<
ui->label_5->text()<<ui->label_6->text()<<ui->label_10->text()<<ui->label_11->text()<<
ui->label_12->text()<<ui->label_13->text();
and you do the same for loading. Why? The "data flows" in the direction of the operator (<< - into the AllTasks). This code does not create a special elements referencing the text objects of your labels.
It does exactly what it does for saving the data to a file. It fills up the AllTasks. Then, you fill it up even more with the data read from the file.
Solution: Change << to >> and move the whole statement to be executed after you're done with reading the file.
Edit: There's no operator>>. Either do:
ui->label->setText(AllTasks.at(0));
ui->label_2->setText(AllTasks.at(1));
...
ui->label_13->setText(AllTasks.at(12));
or:
QVector<QLabel*> labels << ui->label << ui->label_2 << ... << ui->label_13;
for(int i = 0; i < labels.size() && i < AllTasks.size(); ++i)
labels[i]->setText(AllTasks[i]);

QT: Finding and replacing text in a file

I need to find and replace some text in the text file. I've googled and found out that easiest way is to read all data from file to QStringList, find and replace exact line with text and then write all data back to my file. Is it the shortest way? Can you provide some example, please.
UPD1 my solution is:
QString autorun;
QStringList listAuto;
QFile fileAutorun("./autorun.sh");
if(fileAutorun.open(QFile::ReadWrite |QFile::Text))
{
while(!fileAutorun.atEnd())
{
autorun += fileAutorun.readLine();
}
listAuto = autorun.split("\n");
int indexAPP = listAuto.indexOf(QRegExp("*APPLICATION*",Qt::CaseSensitive,QRegExp::Wildcard)); //searching for string with *APPLICATION* wildcard
listAuto[indexAPP] = *(app); //replacing string on QString* app
autorun = "";
autorun = listAuto.join("\n"); // from QStringList to QString
fileAutorun.seek(0);
QTextStream out(&fileAutorun);
out << autorun; //writing to the same file
fileAutorun.close();
}
else
{
qDebug() << "cannot read the file!";
}
If the required change, for example is to replace the 'ou' with the american 'o' such that
"colour behaviour flavour neighbour" becomes "color behavior flavor neighbor", you could do something like this: -
QByteArray fileData;
QFile file(fileName);
file.open(stderr, QIODevice::ReadWrite); // open for read and write
fileData = file.readAll(); // read all the data into the byte array
QString text(fileData); // add to text string for easy string replace
text.replace(QString("ou"), QString("o")); // replace text in string
file.seek(0); // go to the beginning of the file
file.write(text.toUtf8()); // write the new text back to the file
file.close(); // close the file handle.
I haven't compiled this, so there may be errors in the code, but it gives you the outline and general idea of what you can do.
To complete the accepted answer, here is a tested code. It is needed to use QByteArray instead of QString.
QFile file(fileName);
file.open(QIODevice::ReadWrite);
QByteArray text = file.readAll();
text.replace(QByteArray("ou"), QByteArray("o"));
file.seek(0);
file.write(text);
file.close();
I've being used regexp with batch-file and sed.exe (from gnuWin32, http://gnuwin32.sourceforge.net/). Its good enough for replace one-single text.
btw, there is not a simple regexp syntax there. let me know If you want to get some example of script.

Empty file in Qt

I have a file named DBFile.
I am using the following code:
QString DBfile ="C:/Users/E543925/Desktop/VikuTB.xml";
QFile newFile(DBfile);
newFile.open( QIODevice::WriteOnly);
Now I want to write something inside the file if it is empty.
How can I check whether a file is empty or not in Qt?
Check file size before open by newFile.size()
add the append flag and check the insertion pointer:
newFile.open( QIODevice::WriteOnly|QIODevice::Append );
if (newFile.pos() == 0) {
// is empty
} else {
// some data inside
}
disclaimer: untested code, now i'll take the time to try it...
edit: tested, seems to work well...

Creating/writing into a new file in Qt

I am trying to write into a file and if the file doesn't exist create it. I have searched on the internet and nothing worked for me.
My code looks currently like this:
QString filename="Data.txt";
QFile file( filename );
if ( file.open(QIODevice::ReadWrite) )
{
QTextStream stream( &file );
stream << "something" << endl;
}
If I create a text file called Data in the directory, it remains empty. If I don't create anything it doesn't create the file either.
I don't know what to do with this, this isn't the first way in which I tried to create/write into a file and none of the ways worked.
Thanks for your answers.
That is weird, everything looks fine, are you sure it does not work for you? Because this main surely works for me, so I would look somewhere else for the source of your problem.
#include <QFile>
#include <QTextStream>
int main()
{
QString filename = "Data.txt";
QFile file(filename);
if (file.open(QIODevice::ReadWrite)) {
QTextStream stream(&file);
stream << "something" << endl;
}
}
The code you provided is also almost the same as the one provided in detailed description of QTextStream so I am pretty sure, that the problem is elsewhere :)
Also note, that the file is not called Data but Data.txt and should be created/located in the directory from which the program was run (not necessarily the one where the executable is located).
Are you sure you're in the right directory?
Opening a file without a full path will open it in the current working directory. In most cases this is not what you want. Try changing the first line to
QString filename="c:\\Data.txt" or
QString filename="c:/Data.txt"
and see if the file is created in c:\
#include <QFile>
#include <QCoreApplication>
#include <QTextStream>
int main(int argc, char *argv[])
{
// Create a new file
QFile file("out.txt");
file.open(QIODevice::WriteOnly | QIODevice::Text);
QTextStream out(&file);
out << "This file is generated by Qt\n";
// optional, as QFile destructor will already do it:
file.close();
//this would normally start the event loop, but is not needed for this
//minimal example:
//return app.exec();
return 0;
}
Your code is perfectly fine, you are just not looking at the right location to find your file. Since you haven't provided absolute path, your file will be created relative to the current working folder (more precisely in the current working folder in your case).
Your current working folder is set by Qt Creator. Go to Projects >> Your selected build >> Press the 'Run' button (next to 'Build) and you will see what it is on this page which of course you can change as well.
It can happen that the cause is not that you don't find the right directory. For example, you can read from the file (even without absolute path) but it seems you cannot write into it.
In that case, it might be that you program exits before the writing can be finished.
If your program uses an event loop (like with a GUI application, e.g. QMainWindow) it's not a problem. However, if your program exits immediately after writing to the file, you should flush the text stream, closing the file is not always enough (and it's unnecessary, as it is closed in the destructor).
stream << "something" << endl;
stream.flush();
This guarantees that the changes are committed to the file before the program continues from this instruction.
The problem seems to be that the QFile is destructed before the QTextStream. So, even if the stream is flushed in the QTextStream destructor, it's too late, as the file is already closed.
QFile file("test.txt");
/*
*If file does not exist, it will be created
*/
if (!file.open(QIODevice::ReadOnly | QIODevice::Text | QIODevice::ReadWrite))
{
qDebug() << "FAILED TO CREATE FILE / FILE DOES NOT EXIST";
}
/*for Reading line by line from text file*/
while (!file.atEnd()) {
QByteArray line = file.readLine();
qDebug() << "read output - " << line;
}
/*for writing line by line to text file */
if (file.open(QIODevice::ReadWrite))
{
QTextStream stream(&file);
stream << "1_XYZ"<<endl;
stream << "2_XYZ"<<endl;
}