PDA

View Full Version : Fgets after a seek .. catch text after seek



wilcd
15th May 2012, 11:03
i've been some post around trying to know how fgets and the most of the people use readLine ..

my prob comes because i dont want to get the full line ..

i've made a seek inside a text file and now i need to grab ONLY the last 20 chars inside the file

in C i make it with fgets

char ruta[20];

kidboot=fopen("/dos/config.txt","r"); --> cambio.open(QIODevice::ReadOnly | QIODevice::Text);

fseek(kidboot,66,SEEK_SET); --> cambio.seek(66);

fgets(ruta,20,kidboot); --> ?????????????? HOW DO I READ THIS IN QT) so i get only the LAST 20bytes ????????????

greets

mvuori
15th May 2012, 15:09
In fact, people don't use "deadLine", but QFile::readLine()...

Now, when you looked into what functions QFile offers for reading, in QFile class reference, you perhaps did not notice readLineData().

ChrisW67
15th May 2012, 23:33
QFile is a QIODevice so QIODevice::read() is a good place to look.
Of course, your C code will work just fine built into a C++ program also.

Neither set of code will get the last 20 bytes in the file unless the file is exactly 86 bytes long. For that you need to query the length of the file and seek to a point 20 bytes from the end (and handle a file shorter than 20 bytes), or use SEEK_END in your fseek call. You should also check that fseek() or seek() succeeded.

QFile::readLineData() is protected and not useful in this circumstance.

wilcd
16th May 2012, 01:22
what i want is grab the string until EOF,it's not just a task of read those 20bytes because i'm trying tocget a specific root chat inside the text file, in c , i just make a fgets and then a strlen(ruta)-1 ,, but i need to port this to qt

ChrisW67
16th May 2012, 03:27
what i want is grab the string until EOF,
Your original code doesn't do that. Your fgets() call reads up to 20 bytes (including a terminating NUL) from the current location in the file until terminated by the EOL or EOF. So, you might get 20 bytes that don't reach the end of anything, you might get less than 20 bytes reaching the end-of-line or end-of-file.

What you asked for:

i've made a seek inside a text file and now i need to grab ONLY the last 20 chars inside the file

Try this program:


#include <QtCore>
#include <QDebug>
#include <cstdio>

int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);

// Your code
FILE *kidboot;
char ruta[20];
kidboot=fopen("test.txt","r");
fseek(kidboot,66,SEEK_SET);
fgets(ruta,20,kidboot);
fclose(kidboot);
qDebug("Your result: \"%s\"", ruta);

// what your code does
QFile file("test.txt");
QFileInfo info(file);
qint64 fileSize = info.size();
if (fileSize >= 66 && file.open(QIODevice::ReadOnly | QIODevice::Text)) {
if (file.seek(66)) {
QByteArray ba = file.readLine();
ba = ba.left(19);
qDebug("This result: \"%s\"", ba.data());
}
else
qWarning() << "File seek failed";
file.close();
}
else
qWarning() << "File too short";

// what you asked for
if (fileSize >= 20 && file.open(QIODevice::ReadOnly | QIODevice::Text)) {
if (file.seek(fileSize - 20))
qDebug() << "Last 20:" << file.readAll();
else
qWarning() << "File seek failed";
file.close();
}
else
qWarning() << "File too short";

return 0;
}

with this test.txt file to see the difference:


The quick brown fox jumps over the lazy dog a couple of times to make this
long enough.
0 1 2 3 4 5 6 7
01234567890123456789012345678901234567890123456789 012345678901234567890123456789

wilcd
16th May 2012, 17:23
let's test

Added after 18 minutes:

firstly give you thanks for the fast reply to the post ,, meanwhile i've changed the code a little bit and i'm trying to read all the .iso files at the subfolders of a specific root .. it's not
working for a unknows reason .. may you take a glance ? what i do wrong ? thanks in advance for your help

here i took a path_Cat function from some other

char *config::path_cat (const char *str1, char *str2)
{
size_t str1_len = strlen(str1);
size_t str2_len = strlen(str2);
char *result;
result = (char *)malloc((str1_len+str2_len+2)*sizeof *result);
strcpy (result,str1);
size_t i,j;
for(i=str1_len, j=0; ((i<(str1_len+str2_len)) && (j<str2_len));i++, j++)
{
result[i]=str2[j];
}
result[str1_len+str2_len]='\0';
return result;
}

and then i try to read the .iso files inside any subfolder of the main named root (/mount) at this case

char path[255];
struct dirent *dp;

// enter existing path to directory below


const char *dir_path="/mount";

DIR *dir = opendir(dir_path);
if (!dir) return false;

while ((dp=readdir(dir)) != NULL)
{

if (strcmp(dp->d_name,".")==0) continue;
if (strcmp(dp->d_name,"..")==0) continue;

char *tmp;
tmp = path_cat(dir_path, dp->d_name);


if (strstr (tmp, ".iso")!=NULL)
{

ChrisW67
17th May 2012, 00:24
what i do wrong ?

You didn't use
... tags around your code ;)

This is a Qt forum, mostly C++, some Python and little traditional C code, so your questions are slightly misplaced.

Your requirement is easily met by Qt components, without the risk of the memory leakage you probably have e.g. in path_cat(), better handling files containing ".iso" somewhere other than the end of the file name.

You use QDir like this:


#include <QCoreApplication>
#include <QDir>
#include <QDebug>

void scanDir(const QString &path)
{
QDir dir(path);
QStringList filters;
filters << "*.iso";
foreach(const QString &file, dir.entryList(filters, QDir::Files))
qDebug() << dir.filePath(file);
}

int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
scanDir("test");
return 0;
}

wilcd
17th May 2012, 09:27
i used your code,and i've been checking the class doc,but looks like this code only works with specific root,and doesn't look for the .iso files inside the subfolders as i told you at the past post ... how to ?

ChrisW67
17th May 2012, 11:09
Gosh, I don't know, perhaps you could program it to recurse.



#include <QCoreApplication>
#include <QDir>
#include <QDebug>

QStringList scanDir(const QString &path)
{
static const QStringList filters = QStringList() << "*.iso";

QStringList result;
QDir dir(path);
// Add the files in this directory
foreach(const QString &file, dir.entryList(filters, QDir::Files))
result << dir.filePath(file);
// Check the sub directories
foreach(const QString &subdir, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot ))
result << scanDir(dir.filePath(subdir));
return result;
}

int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
qDebug() << scanDir("test");
return 0;
}