Unix Programming - recursively search directories in c/c++

This is Interesting: Free IT Magazines  
Home > Archive > Unix Programming > October 2004 > recursively search directories in c/c++





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author recursively search directories in c/c++
JustSomeGuy

2004-10-26, 5:51 pm

I'm trying to write a c/c++ program that will find all files matching
*.txt from a specific directory downwards...
I've done this on dos/windows before with findfirst/findnext but can't
find the equivalent function calls on unix. (MAC OS X)

(thanks to google)
I've found glob but that just seems to give me a list of directories and
the parameters are not well explained, nor its recursive use.
I've found some postings on opendir/readdir/closedir but I'm not sure
they are giving me anything more that what
glob is giving me... Seems I still need extra code to match filenames
to wild cards like *.txt etc...

I'm concerned with following links and getting stuck in loops...

Surely I'm not the first person to have done this... Does any one have
some code to do this, or a pointer to some?
Perhaps I'm just missing that elusive function call whose name I don't
yet know...

TIA
JSG.


red floyd

2004-10-26, 5:51 pm

JustSomeGuy wrote:
> I'm trying to write a c/c++ program that will find all files matching
> *.txt from a specific directory downwards...
> I've done this on dos/windows before with findfirst/findnext but can't
> find the equivalent function calls on unix. (MAC OS X)
>
> (thanks to google)
> I've found glob but that just seems to give me a list of directories and
> the parameters are not well explained, nor its recursive use.
> I've found some postings on opendir/readdir/closedir but I'm not sure
> they are giving me anything more that what
> glob is giving me... Seems I still need extra code to match filenames
> to wild cards like *.txt etc...
>
> I'm concerned with following links and getting stuck in loops...
>
> Surely I'm not the first person to have done this... Does any one have
> some code to do this, or a pointer to some?
> Perhaps I'm just missing that elusive function call whose name I don't
> yet know...
>
> TIA
> JSG.
>
>


man opendir
man readdir
man closedir
man stat
Måns Rullgård

2004-10-26, 5:51 pm

JustSomeGuy <NoOne@ucalgary.ca> writes:

> I'm trying to write a c/c++ program that will find all files matching
> *.txt from a specific directory downwards...
> I've done this on dos/windows before with findfirst/findnext but can't
> find the equivalent function calls on unix. (MAC OS X)
>
> (thanks to google)
> I've found glob but that just seems to give me a list of directories and
> the parameters are not well explained, nor its recursive use.
> I've found some postings on opendir/readdir/closedir but I'm not sure
> they are giving me anything more that what
> glob is giving me... Seems I still need extra code to match filenames
> to wild cards like *.txt etc...
>
> I'm concerned with following links and getting stuck in loops...
>
> Surely I'm not the first person to have done this... Does any one have
> some code to do this, or a pointer to some?
> Perhaps I'm just missing that elusive function call whose name I don't
> yet know...


ftw, nftw

--
Måns Rullgård
mru@inprovide.com
JustSomeGuy

2004-10-26, 5:51 pm

Måns Rullgård wrote:

> JustSomeGuy <NoOne@ucalgary.ca> writes:
>
>
> ftw, nftw
>


Yes that is a great looking function, unfortunantly its not supported
by MAC OS X.

The hunt goes on...

JustSomeGuy

2004-10-26, 5:51 pm

JustSomeGuy wrote:

> Måns Rullgård wrote:
>
>
> Yes that is a great looking function, unfortunantly its not supported
> by MAC OS X.
>
> The hunt goes on...


I did now find fts.h and its functions fts_open etc...
Any one have a working example?


Bill Marcum

2004-10-26, 5:51 pm

On Tue, 26 Oct 2004 14:19:07 -0600, JustSomeGuy
<NoOne@ucalgary.ca> wrote:
>
> I'm concerned with following links and getting stuck in loops...
>
> Surely I'm not the first person to have done this... Does any one have
> some code to do this, or a pointer to some?
> Perhaps I'm just missing that elusive function call whose name I don't
> yet know...
>

Use the find source code, or use popen() and the find command.


--
"aptitude is also Y2K-compliant, non-fattening, naturally cleansing, and
housebroken."

Heiko

2004-10-26, 8:46 pm

JustSomeGuy wrote:

> I'm trying to write a c/c++ program that will find all files matching
> *.txt from a specific directory downwards...


This works on Linux (and is not thoroughly tested):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <fnmatch.h>
#include <sys/types.h>
#include <unistd.h>
#include <dirent.h>

#define FILENAME_FILTER "*.txt"

int scandirectory(const char *dirname)
{
DIR *dir;
struct dirent *entry;
char path[PATH_MAX];

if (path == NULL) {
fprintf(stderr, "Out of memory error\n");
return 0;
}
dir = opendir(dirname);
if (dir == NULL) {
perror("Error opendir()");
return 0;
}

while ((entry = readdir(dir)) != NULL) {
if (entry->d_type == DT_DIR) {
if (strcmp(entry->d_name, ".")
&& strcmp(entry->d_name, "..")) {
snprintf(path, (size_t) PATH_MAX, "%s/%s", dirname,
entry->d_name);
scandirectory(path);
}
} else if (entry->d_type == DT_REG) {
if (!fnmatch(FILENAME_FILTER, entry->d_name, 0)) {

/*
* This is the place where a file matching the filter is
* found. Do file processing here. Now just
* printing its path.
*/

printf("%s/%s\n", dirname, entry->d_name);
}
}
}
closedir(dir);
return 1;
}


int main(int argc, char *argv[])
{
if (argc != 2) {
fprintf(stderr, "Usage:\t%s <directory>\n", *argv);
return 1;
}
return !scandirectory(argv[1]);
}

/* EOF */


Heiko


Heiko

2004-10-26, 8:46 pm

Small fix: Please remove the part below from the code I posted.

/* <wrong part> */
if (path == NULL) {
fprintf(stderr, "Out of memory error\n");
return 0;
}
/* </wrong part> */


Heiko
Edmund Bacon

2004-10-26, 8:46 pm

JustSomeGuy <NoOne@ucalgary.ca> writes:

> JustSomeGuy wrote:
>
>
> I did now find fts.h and its functions fts_open etc...
> Any one have a working example?


Try this:

========================================
==========================

#include <sys/types.h>
#include <sys/stat.h>
#include <fts.h>
#include <stdio.h>
#include <string.h>

int compar(const FTSENT **f1, const FTSENT **f2)
{
return strcmp( (*f1)->fts_name, (*f2)->fts_name);
}

int is_dot_txt(FTSENT *f)
{
return f->fts_info == FTS_F
&& f->fts_namelen > 4
&& strcmp(f->fts_name + f->fts_namelen - 4, ".txt") == 0;
}

int main(void)
{
FTS *fts;
FTSENT *ftsent;
char * const path[] = { ".", 0};

fts = fts_open(path, FTS_PHYSICAL, compar);

while ( (ftsent = fts_read(fts)) != NULL) {
if ( is_dot_txt(ftsent) ) {
printf("%s\n", ftsent->fts_path);
}
}
fts_close(fts);

return 0;
}

========================================
======================


This should get you going, but you should read the man page and check
the fts_read() return values. If you want to follow links, but check
for loops, you need to use FTS_LOGICAL rather than FTS_PHYSICAL, and
pay attention to fts_cycle.

JustSomeGuy

2004-10-27, 5:52 pm

Many Thanks to all.
B.


Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com