QT Reading binary file and then convert it to QString - c++

I saved the QString in the file like this:
QString str="blabla";
QByteArray _forWrite=QByteArray::fromHex(str.toLatin1());
f.write(_forWrite); // f is the file that is opened for writing.
Then when I read the file I use QFile::readAll() to take the QByteArray but I don't know how to convert it to QString.
I tried to use the constructor that uses QByteArray but It didn't work out. I tried also with QByteArray::data() but same result. What I do wrong ?

It's not clear why you are calling QByteArray::fromHex at all. toLatin1() already return you QByteArray where each symbol encoded with one byte.
[UPDATE]
You should NOT call QByteArray::fromHex at all, because:
invalid characters in the input are skipped
And invalid characters are characters that are not the numbers 0-9 and the letters a-f

You can use QDataStream
#include <QApplication>
#include <QDataStream>
#include <QByteArray>
#include <QFile>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QString strToWrite = "blabla";
QFile fileToWrite("file.bin");
QDataStream dataStreamWriter(&fileToWrite);
fileToWrite.open(QIODevice::WriteOnly);
dataStreamWriter << strToWrite;
fileToWrite.close();
QString strToRead = "";
QFile fileToRead("file.bin");
QDataStream dataStreamReader(&fileToRead);
fileToRead.open(QIODevice::ReadOnly);
dataStreamReader >> strToRead;
fileToRead.close();
qDebug() << strToRead;
return app.exec();
}
Output : "blabla"

Related

Qt Framework Saving inputs To Text File

I was trying to make a little program with Qt Framework C++ .
I made a simple Gui which contains 5 text inputs .
How can I save these inputs into a *.txt file with this schema :
Name : <firstInput>
Lastname : <secondInput>
Age : <ThirdInput>
Nationality : <forthInput>
Address : <fifthInput>
I still didn't do anything in my main.cpp
#include "monformulaire.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MonFormulaire w;
w.show();
return a.exec();
}
Here's an example:
QFile data("output.txt");
if (data.open(QFile::WriteOnly | QFile::Truncate)) {
QTextStream out(&data);
out << ui->lineEdit->text();
}
This tries to save contents of one of the LineEdits into a file named "output.txt". You would put this code into some on-button-clicked slot.
See:
QFile
QTextStream
QLineEdit

Qt separating csv file and storing to differnt variables

#include <QCoreApplication>
#include"administrative.h"
#include"employee.h"
#include"technical.h"
#include<iostream>
#include<string>
#include<QVector>
#include<QFile>
#include<QTextStream>
#include<fstream>
using namespace std;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QFile t("C:\\Users\\User006\\Documents\\EmployeeCSV_Vector\\technical.csv");
if (!t.open(QFile::ReadOnly | QFile::Text))
cout << "ERROR: File open";
QTextStream in(&t);
while (!in.atEnd())
{
QString line=in.readLine();
for (int i=0;i<line.size();i++)
{
QString item=line.split(",");
QString name=item;
QString empCode=item;
QString designation=item;
QString prCode=item;
QString BP=item;
QString DA=item;
QString PA=item;
cout<<name.toStdString()<<"\t";
}
}
t.close();
The above code which I wrote is the code that I wrote to separate a CSV file. The technical.csv file contains some line of values that is separated by commas, I need each value in each line separately in a different variable. But I am not able to do this. Please help me to solve the problem.
Depending on the file structure (does it contain line/column headers, single/multi-line?) you use QString::split() to get a QStringList per line. Then you assign the stringlist items to the variables according to your csv structure knowledge.
I wonder if your code is compiling. According to Qt, the QString::split method returns a QStringList. After the split, you have the items in a list. Assuming all columns are as expected, you can interpret the file as follows:
QTextStream in(&t);
while (!in.atEnd())
{
QStringList items = in.readLine().split(',');
QString name = items.at(0);
...
QString PA = items.at(6);
std::cout<<name.toStdString()<<std::endl;
// do some processing
}

Why QXmlQuery seem to add a ` \n` to results? (and how to solve it?)

Writing a little code to extract some values from an XML, the result of the XPath seem to add \n after the content.
#include <QCoreApplication>
#include <QXmlQuery>
#include <QString>
#include <QDebug>
auto main(int argn, char* argc[])->int
{
QCoreApplication app(argn, argc);
QString replyContent="<Root isOk='ok'/>";
QXmlQuery query;
query.setFocus(replyContent);
query.setQuery("string(//#isOk)");
// Attribute seem to add \n
QString queryResult;
if (query.evaluateTo(&queryResult))
{
qDebug() << queryResult; // Where this \n come from?
qDebug() << queryResult.size(); // Why 3? shouldn't be 2?
}
}
Expected result:
"ok"
2
Given result:
"ok\n"
3
This obviously has some side effects which I would like to avoid.
Why is this \n added? And how to solve it?
I think that this is introduced by the QXmlFormatter that is used when serialising the results to a QString; I suspect that QXmlFormatter::endDocument writes a newline.
One workaround would be to output to a string list instead, then pick the first element:
QStringList results;
if (query.evaluateTo(&results))
{
const QString& queryResult = results.first();
qDebug() << queryResult;
qDebug() << queryResult.size();
}
You might choose to join() the results instead, if you need them all.
Alternatively you can take full control of the serialization and use either QXmlSerializer or QXmlFormatter. That way you will have in the output whatever you ask, not some defaults you are provided with. It will have more code, that's true but the intent will be clearer than just discarding some newline at the end.
Here is an example of how to do it with QXmlSerializer (which produces no redundant symbols by default):
#include <QCoreApplication>
#include <QXmlQuery>
#include <QXmlSerializer>
#include <QString>
#include <QBuffer>
#include <QDebug>
auto main(int argn, char* argc[])->int
{
QCoreApplication app(argn, argc);
QString replyContent="<Root isOk='ok'/>";
QXmlQuery query;
query.setFocus(replyContent);
query.setQuery("string(//#isOk)");
QBuffer buffer;
buffer.open(QBuffer::ReadWrite);
QXmlSerializer serializer(query, &buffer);
if (query.evaluateTo(&serializer))
{
QString queryResult = QString::fromUtf8(buffer.buffer());
qDebug() << queryResult;
qDebug() << queryResult.size();
}
}

Qt convert unicode entities

In QT 5.4 and C++ I try to decode a string that has unicode entities.
I have this QString:
QString string = "file\u00d6\u00c7\u015e\u0130\u011e\u00dc\u0130\u00e7\u00f6\u015fi\u011f\u00fc\u0131.txt";
I want to convert this string to this: fileÖÇŞİĞÜİçöşiğüı.txt
I tried QString's toUtf8 and fromUtf8 methods. Also tried to decode it character by character.
Is there a way to convert it by using Qt?
Qt provides a macro called QStringLiteral for handling string literals correctly.
Here's a full working example:
#include <QString>
#include <QDebug>
int main(void) {
QString string = QStringLiteral("file\u00d6\u00c7\u015e\u0130\u011e\u00dc\u0130\u00e7\u00f6\u015fi\u011f\u00fc\u0131.txt");
qDebug() << string;
return 0;
}
As mentioned in the above comments, you do need to print to a console that supports these characters for this to work.
I have just tested this code:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QString s = "file\u00d6\u00c7\u015e\u0130\u011e\u00dc\u0130\u00e7\u00f6\u015fi\u011f\u00fc\u0131.txt";
qDebug() << s.length(); //Outputs: 22
qDebug() << s; //Outputs: fileÖÇŞİĞÜİçöşiğüı.txt
return a.exec();
}
This is with Qt 5.4 on ubuntu, so it looks like your problem is with some OS only.
#include <QTextDocument>
QTextDocument doc;
QString string = "file\u00d6\u00c7\u015e\u0130\u011e\u00dc\u0130\u00e7\u00f6\u015fi\u011f\u00fc\u0131.txt";
doc.setHtml(string); // to convert entities to text
QString result = doc.toPlainText(); // result = "fileÖÇŞİĞÜİçöşiğüı.txt"
NOT USEFUL if you have a CONSOLE app
QTextDocument needs the GUI module.

Providing relative file path

I have text files in my resource file and I'd like to be able to provide a path for this file to std::ifstream. Neither :\file_name.txt nor ..\file_name.txt works.
Does anyone know how to fix it?
Qt resource files are not filesystem files. Those files are loaded in memory as static char arrays. You can see for yourself looking in your build directory for qrc_*.cpp files. You can get data from there if you want, or you might want to use QTextStream for reading those, using the QIODevice constructor with a QFile.
You don't specify what you want to do exactly, but this is a sample that reads what is inside the file:
#include <QtCore/QCoreApplication>
#include <QTextStream>
#include <QFile>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QFile file(":/test.txt");
QTextStream stream(&file);
if (!file.open(QIODevice::ReadOnly)) {
qFatal("Failed to open file.");
return -1;
}
QString text = stream.readAll();
if (text.isNull()) {
qDebug("Failed to read file.");
return -1;
}
qDebug("File content is: %s. Bye bye.", qPrintable(text));
return 0;
}