I'm trying to read in a file of trace addresses (each on their own line) and append to the front of each. This input file is intended to be the engine of a cache emulator i'm trying to build. I am having issues reading the file in without getting into an infinite loop. When I change the do-while to run on a false condition, I get the proper output for just the do segment. Therefore, I know I'm running into an infinite loop issue with how I worded my while segment. Maybe i'm fatigued and can't see the issue with this function:
void MainWindow::readFile(){
infoLabel->setText(tr("Invoked <b>File|Open</b>"));
QString filename="trace.txt";
QString path = QDir::currentPath();
QFile file("//Users//nathan1324//Desktop//trace.txt");
//file.open(QIODevice::ReadOnly);
if(!file.exists()){
qDebug() << "File cannot be found "<<filename;
qDebug() << " " << path;
}else{
qDebug() << filename<<" Opening...";
}
QString line;
textEdit->clear();
if (file.open(QIODevice::ReadOnly | QIODevice::Text)){
QTextStream stream(&file);
do {
line = stream.readLine();
textEdit->setText(textEdit->toPlainText()+"0x"+line+"\n");
qDebug() << "line: "<<line;
} while (!line.isNull());
}
file.close();
}
Any suggestions of an alternative way to write this function?
To add items use the append function of QTextEdit:
void QTextEdit::append(const QString & text)
Appends a new paragraph with text to the end of the text edit.
Note: The new paragraph appended will have the same character format
and block format as the current paragraph, determined by the position
of the cursor.
To iterate through the QTextStream atEnd()
bool QTextStream::atEnd() const
Returns true if there is no more data to be read from the QTextStream;
otherwise returns false. This is similar to, but not the same as
calling QIODevice::atEnd(), as QTextStream also takes into account its
internal Unicode buffer.
Code:
void MainWindow::readFile(){
infoLabel->setText(tr("Invoked <b>File|Open</b>"));
QString filename = "trace.txt";
QString path = QDir::currentPath();
QFile file("//Users//nathan1324//Desktop//trace.txt");
if(!file.exists()){
qDebug() << "File cannot be found "<<filename;
qDebug() << " " << path;
return;
}
QString line;
textEdit->clear();
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)){
qDebug() << "Could not open file" << filename;
return;
}
qDebug() << filename<<" Opening...";
QTextStream stream(&file);
while (!stream.atEnd()) {
line = stream.readLine();
if(!line.isNull()){
textEdit->append("0x"+line);
qDebug() << "line: "<<line;
}
}
file.close();
}
Use atEnd to detect the end of a stream:
bool QTextStream::atEnd() const
Returns true if there is no more data to be read from the QTextStream;
otherwise returns false. This is similar to, but not the same as
calling QIODevice::atEnd(), as QTextStream also takes into account its
internal Unicode buffer.
while (!stream.atEnd()) {
line = stream.readLine();
textEdit->setText(textEdit->toPlainText()+"0x"+line+"\n");
qDebug() << "line: "<<line;
}
Related
I am attempting to compare a QByteArray of an already saved html file with a QByteArray that was just downloaded. I have to convert the QString of the file's contents to QByteArray in order to compare them (or vice versa) and comparing bytes seems like the cleanest method, however when converted from QString to QByteArray, the size of the new QByteArray is smaller than what it should be. QByteArray QString::toLocal8Bit() const states that if it is undefined, the characters will be suppressed or replaced. It also said that it uses toLatin1() by default and tried to use ASCII since that is what a website is encoded in. I still get the same results.
bool NewsBulletin::compareDownload(QByteArray new_contents, QString filename)
{
bool return_what = false;
qDebug() << "I am in compareDownload";
// qDebug() << new_contents[1];
// qDebug() << new_contents[1] << endl
// << new_contents[2];
QFile file(application_path + filename);
if (file.exists())
{
// QString new_contents_qstr(new_contents);
file.open(QIODevice::ReadOnly | QIODevice::Text);
QTextStream in(&file);
QTextCodec::setCodecForLocale(QTextCodec::codecForName("ASCII"));
QString file_contents = in.readAll();
QByteArray file_byte_array = file_contents.toLocal8Bit();
qDebug() << "outputting new file array";
qDebug() << new_contents[5] << new_contents.size();
qDebug() << "outputting old file array";
qDebug() << file_byte_array[5] << file_byte_array.size();
for (int i=0; i<=file_byte_array.size(); i++)
{
if (file_byte_array[i] != new_contents[i])
{
return_what = true;
break;
}
else if (i == file_byte_array.size())
{
qDebug() << "compareDownload will return false, duplicate file.";
return_what = false;
}
}
}
else
{
qDebug() << "compareDownload will return true, DNE.";
return_what = true;
}
return return_what;
}
The output of the qDebug() from the function is:
I am in compareDownload
outputting new file array
T 64704
outputting old file array
T 64576
After reading the api for hours, I found the reason for the bytes being different.
file.open(QIODevice::ReadOnly | QIODevice::Text);
QIODevice::Text needs to be removed. This flag changes end of line terminators into the terminator for cpp, "\n", thus giving a byte difference.
I'm trying to read a text file and display the contents in a QPlainTextEdit. Please can you point out what I'm doing wrong:
QFile jsonFile("data.json");
if (!jsonFile.open(QIODevice::ReadOnly | QIODevice::Text))
{
qDebug() << "Failed to open file";
qDebug() << jsonFile.errorString();
return;
}
else
{
qDebug() << "File opened";
} //It returns that the file opened successfully
qDebug() << "File Exists?: " << jsonFile.exists(); //Yep, it exists.
QTextStream outStream(&jsonFile);
QString textString = outStream.readAll();
qDebug() << "Text string: " << textString; //textString is empty! ""
ui->fileToPost->setPlainText(textString); //fileToPost is the QPlainTextEdit
jsonFile.close();
If I do something like
QString textString = "The cat sat on the mat";
it displays fine. The problem is that nothing is being read from the stream (or maybe the file).
Try to check file's absolute path, probably it is not where, you expect it: qDebug()<<QFileInfo("data.json").absoluteFilePath();
I'm currently create an apps in Meego using QML and JS on most of the part. and now I stumbled upon a problem.
From javascript I want to call a C++ function to read text file, parse it, and then return an array of the parsing result.
so I create a Q_INVOKABLE function called parse() and call it through javascript
function parse() {
var myArray = new Array();
myArray = parser.parse("/home/user/MyDocs/angklungtext.txt")
if(myArray === undefined){
console.log("null found");
}
for(var i = 0; i < myArray.length; i++){
console.log(myArray[i][0] + "," + myArray[i][1])
}
}
and here is the parse function in C++
QVariantList* QMLParser::parse(QString filename)
{
qDebug() << "start debugging";
qDebug() << filename;
qDebug() << QDir::currentPath();
QDir dir;
qDebug()<< dir.absoluteFilePath(filename);
QFile file(filename);
if(!file.exists())
{
qDebug() << "File: " << file.fileName() << "tidak ditemukan";
return NULL;
}
if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
{
qDebug() << "Tidak dapat membuka file" << file.fileName() << "untuk ditulis";
return NULL;
}
QTextStream stream(&file);
QVariantList* myList = new QList<QVariant>;
while(!stream.atEnd())
{
QString line = stream.readLine();
qDebug() << line.trimmed();
QStringList lineList = line.split(":");
myList->append(lineList);
}
file.close();
return myList;
}
sadly.
when I try to run it it giving a result like this
start debugging
"/home/user/MyDocs/angklungtext.txt"
"/home/developer"
"/home/user/MyDocs/angklungtext.txt"
"1:1000"
"4:2000"
"5:3000"
"2:4000"
null found
file:///opt/memoryreader/qml/memoryreader/myjs.js:8: TypeError: Result of expression 'myArray' [undefined] is not an object.
looks like the C++ parse function successfully parsing the file. it can read it and it can save it into the QVariantList.
but after it return the result into javascript myArray still [undefined].
is there something wrong with the conversion?
Just simplify the C++ side like this :
QVariant QMLParser::parse(QString filename)
{
QStringList myList;
qDebug() << "start debugging";
qDebug() << filename;
qDebug() << QDir::currentPath();
QDir dir;
qDebug() << dir.absoluteFilePath(filename);
QFile file(filename);
if(!file.exists()) {
qDebug() << "File: " << file.fileName() << "tidak ditemukan";
return NULL;
}
if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qDebug() << "Tidak dapat membuka file" << file.fileName() << "untuk ditulis";
return NULL;
}
QTextStream stream(&file);
while(!stream.atEnd()) {
QString line = stream.readLine();
qDebug() << line.trimmed();
myList << line.trimmed().split(":");
}
file.close();
return QVariant::fromValue(myList);
}
And it should work !
Just remember, QML must see a QVariant, even if a QList is wrapped inside it, and Qt is able to convert most of its base types to QVariant using QVariant::fromValue(T) so use it extensively.
Oh and BTW a QVariant is reference not pointer.
Haven't done this myself, so I'm just thinking out loud. But I note that you're returning a pointer to a QVariantList...which looks suspect. (Also: if you new, then who would do the delete?)
Have you tried returning it by value?
I'm using Qt to develop my C++ application using QML as well.
Here's my code
QFile inputFile("data.txt");
//QFile inputFile("/:data.txt");
qDebug() << "Hello:";
if (!inputFile.open(QIODevice::ReadOnly | QIODevice::Text))
{
qDebug() << "Wasn't ready:";
}
else{
qDebug() << "Txt file ready:";
QTextStream in(&inputFile);
while ( !in.atEnd() )
{
QString line = in.readLine();
qDebug() << "message: " << line;
}
}
I was wondering why it doesn't work. The console always prints "Wasn't ready".
Please help.
In the error handling block where you do qDebug() << "Wasn't ready:"; you should call inputFile.error() and print out the returned value to get more details of what went wrong.
It might also be an idea to start the program with printing out the current directory, to make sure that the file is searched for in the correct location.
To illustrate my problem I will give you an example:
I have UTF-8 encoded text file.
in.txt:
ąśćź
ąś
ŻźŹ
This program reads in.txt line by line and produces duplicate out.txt.
It not only duplicates the file but also prints it to console.
At the end it creates QString with the same text as the first line of file.
#include <QtCore>
int main()
{
QVector<QString> qv;
QFile file("in.txt");
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return -1;
QTextStream in(&file);
in.setCodec("UTF-8");
while (!in.atEnd())
{
QString line = in.readLine();
qv.append(line);
}
QFile file2("out.txt");
if (!file2.open(QIODevice::WriteOnly | QIODevice::Text))
return -1;
QTextStream out(&file2);
out.setCodec("UTF-8");
for (int i = 0; i < qv.size(); ++i)
{
//Debugging output
qDebug() << qv[i];
out << qv[i] << "\n";
}
// Important part!!!
qDebug() << "Why?";
QString s("ąśćź"); //same as the first line of file!
qDebug() << s;
}
The console output is a mystery:
"????"
"??"
"???"
Why?
"ąśćź"
out.txt: (duplicate)
ąśćź
ąś
ŻźŹ
Why does it firstly print "????" to the console while making a duplicate and then prints "ąśćź" when I hardcode "ąśćź" into my program? What seems to be the problem?
It creates identical copy of in.txt, so QString and TextStreams work fine.
Thanks in advance.
This is no answer to why this is happening, but doing
for (int i = 0; i < qv.size(); ++i)
{
//Debugging output
qDebug() << qv[i].toUtf8();
out << qv[i] << "\n";
}
seems to fix it.