Qt read specific columns of tab delimited text file - c++

I'm working on a program that reads a text file of tab delimited doubles and sums up each column, effectively calculating the integral of each column.
What I want to be able to do is choose a specific column to sum up rather than sum all the columns.
The code I've already got working for the integral of all columns:
void MainWindow::on_pushButton_clicked()
{
data::SingleLineData.resize(512);
QString test;
QString inputfile = QFileDialog::getOpenFileName(
this,
tr("Open File"),
"/Users",
"All files (*.*)"
);
if(inputfile != ""){
QFile file(inputfile);
if(!file.open(QFile::ReadOnly)){
}
QTextStream in(&file);
double buffer;
while(!file.atEnd()){
in.readLine();
for(int i=0; i<512; i++){
in >> buffer;
data::SingleLineData[i]+=buffer;
}
}
}
qDebug() << data::SingleLineData;
// ************* file output **************************************************
QString filename = QFileDialog::getSaveFileName(
this,
tr("Save File"),
"/Users",
"Text files (*.txt)"
);
QFile fileout(filename);
if (fileout.open(QFile::ReadWrite | QFile::Truncate)){
QTextStream out(&fileout);
for (QVector<double>::iterator iter = data::SingleLineData.begin(); iter != data::SingleLineData.end(); iter++){
out << *iter <<", ";
}
fileout.close();
}
}
And here is my attempt at choosing out an individual column using an integer input into a spin box:
void MainWindow::on_pushButton_2_clicked()
{
QString inputfile = QFileDialog::getOpenFileName(
this,
tr("Open File"),
"/Users",
"All files (*.*)"
);
QVector<double> SingleChannel;
if (inputfile != ""){
QFile file(inputfile);
if (!file.open(QIODevice::ReadOnly)){
}
QTextStream in(&file);
SingleChannel.resize(1);
double buffer;
int channelnumber = ui->spinBox->value();
while(!file.atEnd()){
in.readLine();
for (int i = 0; i < 512; i++){
in >> buffer;
if (i == channelnumber){
SingleChannel.push_back(buffer);
}
data::SingleLineData[i]+=buffer;
}
}
}
qDebug() << SingleChannel;
}
I get the following error though:
ASSERT failure in QVector<T>::operator[]: "index out of range", file /Users/mduncan/Qt/5.3/clang_64/lib/QtCore.framework/Headers/qvector.h, line 385
The program has unexpectedly finished.
Anyone have any ideas?
Thanks :)

add this line at the beginning of void MainWindow::on_pushButton_2_clicked method
data::SingleLineData.resize(512);
this will resize your container to 512 defaulted value count elements. Because you use data::SingleLineData[i]+=buffer, which need access the i th element in the container.

Related

Do-while infinite loop in Qt

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;
}

QML - How display a text file on ListView?

I want to do a telnet client. There is no problem to connect modem and read QTcpSocket.
void iDirectClient::when_socket_ready_read() {
QByteArray ba = m_socket->readAll();
qDebug() << "\r\nRead:\r\n" << ba;
QString filename = "my_file.txt";
QFile file(filename);
if (file.open(QIODevice::ReadWrite)) {
QTextStream stream(&file);
stream << ba << endl
}
file.close();
}
and I use FileIO for read a text file in QML.Here is my code:
QFile file(m_source);
QString fileContent;
if ( file.open(QIODevice::ReadOnly) ) {
QString line;
QTextStream t( &file );
do {
line = t.readLine();
fileContent += line;
}
while (!line.isNull());
qDebug() << "SOURCE" << line;
file.close();
file.remove();
}
When I create my_file.txt, there is no problem. It seems like
"677 = T12V_KU_SAT
623 = SBC2_KU_SEA
615 = IS19_KU_SWP" (these are beam list.)
but I read this text file in QML, with this code:
FileIO {
id: myFile
source: "my_file.txt"
onError: console.log(msg)
Component.onCompleted: {
}
}
Component.onCompleted: {
console.log(myFile.read())
textarea1.text = myFile.read();
}
"677 = T12V_KU_SAT623 = SBC2_KU_SEA615 = IS19_KU_SWP" output is like this.
I want to display every beam in listview because I need to beams names are clickable.There is a problem with line feed.
I hope I explained clear my problem.Thank you!
The string returned by QTextStream::readLine() does not contain end-of-line characters according to the documentation.

Why is the QByteArray read from a file smaller than the newly downloaded QByteArray?

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.

Rename file if button is pressed in TreeView Qt

I have a treeview that displays a folder with text files. There is a 'open' button. That will open the file. But when this button is pressed it should rename the file to: read filename.txt. So if there is a file for example that is name nameslist.txt and the button is pressed it should rename it to read nameslist.txt or something similar. I thought of something like this:
void berichtenhistorie::on_Openbutton_released()
{
QModelIndex index = ui->treeView->currentIndex();
QString name = index.fileName();
QString path = index.filePath();
QFile file(path);
file.open(QIODevice::WriteOnly | QIODevice::Text);
file.rename("read " + name);
file.close();
}
But this isnt working. I get the following error's:
error: C2352: 'QDirModel::fileName' : illegal call of non-static member function
But I dont know how to use fileName() and filePath() correctly.
Thanks for help!
I think that here is what you looking for:
void berichtenhistorie::on_Openbutton_released()
{
QModelIndex index = ui->treeView->currentIndex();
QFileSystemModel *model = (QFileSystemModel*)ui->treeView->model();
QString path = model->filePath(index);
QString name = model->fileName(index);
QString dir = path;
dir.remove(dir.size() - name.size(), name.size());
QFile file(path);
if(file.open(QIODevice::WriteOnly | QIODevice::Text))
{
//Interact with the file
file.close();
if(file.rename(QString("%1read %2").arg(dir, name)))
qDebug() << "Renamed";
}
}
Here's a break out of each step you'll need to do to work with QFile.
QFile file("test.txt");
if(file.exists())
{
qDebug() << "found file";
if(file.open(QIODevice::ReadWrite))
{
qDebug() << "opened";
if(file.rename("text1.txt"))
{
qDebug() << "renamed";
}
else
{
qDebug() << "failed to rename";
}
file.close();
}
}
else
{
qDebug() << "file does not exist";
}
In the end, you'll only really need your debugger to step through instead of printing out everything known to your application. E.g.
QFile file("test.txt");
if(file.exists() && file.open(QIODevice::ReadWrite))
{
if(file.rename("text1.txt"))
{
qDebug() << "renamed";
}
file.close();
}

Qt and UTF-8: strange behaviour

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.