My goal is to see how many lines in each file (.h and .cpp).
I can only see the files in the current directory, sorted by size for now.
I need to set path by using QString. Then, maybe QDir and QFiles can be useful.
Thanks for your precious time.
QDir dir;
dir.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks);
dir.setSorting(QDir::Size | QDir::Reversed);
QFileInfoList list = dir.entryInfoList();
qInfo() << " Bytes Filename" << Qt::endl;
for(int i=0; i<list.size(); i++)
{
QFileInfo fileInfo = list.at(i);
std::cout << qPrintable(QString("%1 %2").arg(fileInfo.size(), 10)
.arg(fileInfo.fileName()));
std::cout << std::endl;
}
Related
I am using 7za.exe as subprocess to unzip the files with qt and cpp. I used a checkbox to include the option of recursive unzipping, the recursive option does not seem to work here. Could anyone suggest where I am doing wrong?
void MainWindow::uncompressZipFile()
{
QStringList queryArguments;
queryArguments << "e";
queryArguments << """" + choosenDir + """"+"/*.zip";
if(ui->checkBox->isChecked())
queryArguments << "-ro"+choosenDir+"/example";
queryArguments << "-o"+choosenDir+"/example";
QFileInfoList dirs;
QFileInfoList files;
for(int i=0; i < dirs.size(); i++)
{
qDebug() << "Directories listed here";
qDebug() << dirs.at(i);
}
QDirIterator it(choosenDir, QStringList() << "*.zip", QDir::Files, QDirIterator::Subdirectories);
while (it.hasNext()){
qDebug() << it.next();
ui->resultList->addItem(it.next());
}
zipperProcess.setWorkingDirectory(QCoreApplication::applicationDirPath());
qDebug() << zipperProcess.workingDirectory();
qDebug()<<queryArguments;
zipperProcess.start("7za.exe", queryArguments);
}
I got this code from a book. When I ran on Visual Studio, it said to switch strcpy() to strcpy_s(), and after I did that, it seems the program terminated at the delete pointer. I tried to run on Dev-C++, and it works fine. Anyone knows why? Thank you.
#include "pch.h"
#include <iostream>
#include <cstring>
int main()
{
cout << "Enter a kind of animal: ";
cin >> animal; // ok if input < 20 chars
ps = animal; // set ps to point to string
cout << ps << "!\n"; // ok, same as using animal
cout << "Before using strcpy():\n";
cout << animal << " at " << (int *)animal << endl;
cout << ps << " at " << (int *)ps << endl;
ps = new char[strlen(animal) + 1]; // get new storage
strcpy_s(ps, sizeof(animal), animal); // copy string to new storage
cout << "After using strcpy():\n";
cout << animal << " at " << (int *)animal << endl;
cout << ps << " at " << (int *)ps << endl;
delete[] ps;
return 0;
}
I am beginner in UI design using Qt. My project now is doing comparison. For example: if I have 2 text file.
How can I compare the number line by line? Because I have so many text file like this, and I need compare them on by one.What I can do now is only read the text file by line order. Thank you so much!
The procedure is simple
Read both files (always make sure they are opened successfully)
Read files line by line and convert strings to numbers for comparison.
Quit if there is no data left.
Moreover, you need to make sure that the format of files is consistent otherwise, you need to make sure what you manipulate is a real number. I assume numbers are integers but of course you can change it. Extra precautions are required in this kind of project. I will leave it to you. The simplified code for the above procedure is
#include <QString>
#include <QFile>
#include <QDebug>
#include <QTextStream>
int main()
{
QFile data1("text1.txt");
if (!data1.open(QIODevice::ReadOnly | QIODevice::Text)){
qDebug() << "text1.txt file can't be opened...";
return -1;
}
QFile data2("text2.txt");
if (!data2.open(QIODevice::ReadOnly | QIODevice::Text)){
qDebug() << "text2.txt file can't be opened...";
return -1;
}
QTextStream in1(&data1), in2(&data2);
while ( !in1.atEnd() && !in2.atEnd() ) {
QString num1 = in1.readLine();
QString num2 = in2.readLine();
if ( num1.toInt() > num2.toInt() )
qDebug() << num1.toInt() << ">" << num2.toInt();
// do the rest of comparison
}
return 0;
}
Now in my case, the txt files are
text1.txt
1
2
3
4
text2.txt
3
5
1
6
The output is
3 > 1
Edit: the OP is looking for the difference and its sum.
int sum(0);
while ( !in1.atEnd() && !in2.atEnd() ) {
QString num1 = in1.readLine();
QString num2 = in2.readLine();
int result = num1.toInt() - num2.toInt();
qDebug() << num1.toInt() << "-" << num2.toInt() << " = " << result;
sum += result;
}
qDebug() << "sum = " << sum;
Basic approach would be something like this:
QString filename1("C:/Users/UserName/Downloads/t1.txt");
QString filename2("C:/Users/UserName/Downloads/t2.txt");
QFile file(filename1);
file.open(QIODevice::ReadOnly);
QTextStream in(&file);
QStringList textOfFile1;
while (!in.atEnd()) {
QString line = in.readLine();
textOfFile1.append(line);
}
QFile file2(filename2);
file2.open(QIODevice::ReadOnly);
QTextStream in2(&file2);
QStringList textOfFile2;
while (!in.atEnd()) {
QString line = in.readLine();
textOfFile2.append(line);
}
if(textOfFile1.size() != textOfFile2) return false;
for(int i = 0; i < textOfFile1.size(); i++)
{
if(textOfFile1[i] != textOfFile2[i]) return false;
}
return true;
i.e. You read the files into a QStringList and you compare the lists line by line. This way you can also catch the firs # of line where there was a mismatch. Note that such comparison also considers white spaces such as \n \t etc.
PS: wrap the readers into functions, to avoid duplication like me. :)
Hope this helps ;)
I want to use QSettings to save my window's dimensions so I came up with these two functions to save & load the settings:
void MainWindow::loadSettings()
{
settings = new QSettings("Nothing","KTerminal");
int MainWidth = settings->value("MainWidth").toInt();
int MainHeight = settings->value("MainHeight").toInt();
std::cout << "loadSettings " << MainWidth << "x" << MainHeight << std::endl;
std::cout << "file: " << settings->fileName().toLatin1().data() << std::endl;
if (MainWidth && MainHeight)
this->resize(MainWidth,MainHeight);
else
this->resize(1300, 840);
}
void MainWindow::saveSettings()
{
int MainHeight = this->size().height();
int MainWidth = this->size().width();
std::cout << "file: " << settings->fileName().toLatin1().data() << std::endl;
std::cout << "saveSettings " << MainWidth << "x" << MainHeight << std::endl;
settings->setValue("MainHeight",MainHeight);
settings->setValue("MainWidth",MainWidth);
}
Now, I can see the demensions being extracted in saveSettings as expected but no file gets created and hence loadSettings will always load 0 only. Why is this?
QSettings isn't normally instantiated on the heap. To achieve the desired effect that you are looking for, follow the Application Example and how it is shown in the QSettings documentation.
void MainWindow::readSettings()
{
QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName());
const QByteArray geometry = settings.value("geometry", QByteArray()).toByteArray();
if (geometry.isEmpty()) {
const QRect availableGeometry = QApplication::desktop()->availableGeometry(this);
resize(availableGeometry.width() / 3, availableGeometry.height() / 2);
move((availableGeometry.width() - width()) / 2,
(availableGeometry.height() - height()) / 2);
} else {
restoreGeometry(geometry);
}
}
void MainWindow::writeSettings()
{
QSettings settings(QCoreApplication::organizationName(), QCoreApplication::applicationName());
settings.setValue("geometry", saveGeometry());
}
Also note the use of saveGeometry() and restoreGeometry(). Other similarly useful functions for QWidget based GUIs are saveState() and restoreState() (not shown in the above example).
I strongly recommend the zero parameter constructor of QSettings, and to setup the defaults in your main.cpp, like so:
QSettings::setDefaultFormat(QSettings::IniFormat); // personal preference
qApp->setOrganizationName("Moose Soft");
qApp->setApplicationName("Facturo-Pro");
Then when you want to use QSettings in any part of your application, you simply do:
QSettings settings;
settings.setValue("Category/name", value);
// or
QString name_str = settings.value("Category/name", default_value).toString();
QSettings in general is highly optimized, and works really well.
Hope that helps.
Some other places where I've talked up usage of QSettings:
Using QSettings in a global static class
https://stackoverflow.com/a/14365937/999943
Recently I programmed to do file transmission with Qt. Thought it worked now, I'm still curious about what happened. Please help me find out the reason. Many thanks.
Why the size of head is bigger than the sum of sizeof(qin32), sizeof(qint32) and length of file name?(I guess it is the reason of function - setVersion())
QFileInfo info(file_to_send.fileName());
QByteArray head;
QDataStream out(&head, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_5_0);
out << qint32(file_to_send.size() + info.fileName().length() + sizeof(qint32)*2)
<< qint32(info.fileName().length())
<< info.fileName();
tcpClient.write(head);
You have made it to complicated. Pattern is like that:
QFileInfo info(file_to_send.fileName());
QByteArray head;
QDataStream out(&head, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_5_0);
out << qint32(0)
<< info.fileName(); // << YouCanAddMoreStuffHere;
out.device()->seek(0);
out << qint32(out.length());
tcpClient.write(head);
and read code:
void SomeClass::slotReadClient() { // slot connected to readyRead signal of QTcpSocket
QTcpSocket *tcpSocket = (QTcpSocket*)sender();
QDataStream clientReadStream(tcpSocket);
while(true) {
if (!next_block_size) {
if (tcpSocket->bytesAvailable() < sizeof(qint32)) { // are size data available
break;
}
clientReadStream >> next_block_size;
}
if (tcpSocket->bytesAvailable() < next_block_size) {
break;
}
QString fileName;
clientReadStream >> fileName; // >> YouCanAddMoreStuffHere; // same as above
next_block_size = 0;
}
}
info.filename() writes out its own length
if you don't want that then you can do
QFileInfo info(file_to_send.fileName());
QByteArray head;
QDataStream out(&head, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_5_0);
QByteArray filename = info.fileName().toLatin1();
out << qint32(file_to_send.size() + filename .length() + sizeof(qint32)*2);
<< qint32(filename .length())
out.writeRawData(fileName.constData(), filename.length());
tcpClient.write(head);
using writeRawData which bypasses any built in encoding