C++ directory operations

GEC: Discuss gaming, computers and electronics and venture into the bizarre world of STGODs.

Moderator: Thanas

Post Reply
Miles Teg
Padawan Learner
Posts: 300
Joined: 2002-07-21 06:11pm

C++ directory operations

Post by Miles Teg »

So,

I am currently trying to teach myself c++, and I've run into a problem.

How does one get a directory listing (in a unix environment)? I.E. I want to get a listing of "/home/user". I've been trying to figure it out for .. well, too long now. I've found nothing via Google in about a hour of searching.

Also, I am mostly a Java progammer, so I was hoping to find an online resource like the Java API for (ANSI) C++ standard library. Can anyone point me to one?

Miles Teg
Now I am become death -- the shatterer of worlds...
-- Oppenheimer 1945
User avatar
Chris OFarrell
Durandal's Bitch
Posts: 5724
Joined: 2002-08-02 07:57pm
Contact:

Post by Chris OFarrell »

What exactly are you talking abuot. Do you intend to pass a directory listing to your program to do some work on it?

In that case, just redirect stdin into your program and use CIN to suck up the listing into some kind of data structure. Thoguh frankly for a job like that, I would actualy use C rather then C++, scanf makes filter jobs like that about ten times easier.
Image
User avatar
Spacebeard
Padawan Learner
Posts: 473
Joined: 2005-03-21 10:52pm
Location: MD, USA

Re: C++ directory operations

Post by Spacebeard »

Miles Teg wrote:So,

I am currently trying to teach myself c++, and I've run into a problem.

How does one get a directory listing (in a unix environment)? I.E. I want to get a listing of "/home/user". I've been trying to figure it out for .. well, too long now. I've found nothing via Google in about a hour of searching.
Depends on what you're trying to do. If all you want to do is present this listing to the user, then calling system("/bin/ls /home/user") is probably a good bet.

If you want to do something for each file in a given directory, then the standard C functions opendir(3c), readdir(3c), and closedir(3c) will work just as well in C++. Check their man pages for usage.
Also, I am mostly a Java progammer, so I was hoping to find an online resource like the Java API for (ANSI) C++ standard library. Can anyone point me to one?
http://www.cplusplus.com/ref/

Also, the C standard library, which you'll of course normally borrow pretty heavily from when programming C++, is well documented by man pages on most UNIX systems. Look in section 3c in Solaris or HP-UX, or section 3 in *BSD (and probably Linux).
"This war, all around us, is being fought over the very meanings of words." - Chad, Deus Ex
User avatar
Antares
Padawan Learner
Posts: 489
Joined: 2003-12-04 03:13am

Post by Antares »

Perhaps this will help if you want the content of a directory:

Code: Select all

#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <stdio.h>
#include <io.h>

//struct _finddata_t {
//    unsigned    attrib;
//    time_t      time_create;    /* -1 for FAT file systems */

//    time_t      time_access;    /* -1 for FAT file systems */
//    time_t      time_write;
//    _fsize_t    size;
//    char        name[260];
//};
struct lst {
   struct _finddata_t info;
   struct lst* next;
};

void main() {
   char buf[1024];
   struct _finddata_t info;
   struct lst* first = (struct lst*) calloc(1,sizeof(struct lst));
   struct lst* next = first;
   char* env = getenv("DIR");
   strcpy((char*)buf,env);
   strcat((char*)buf,"\\*.*");
   long h = _findfirst(buf, &next->info);
   next->next = (struct lst*) calloc(1,sizeof(struct lst));
   while(!_findnext(h, &next->info)) {
      next->next = (struct lst*) calloc(1,sizeof(struct lst));
      next = next->next;
   
   }
   next=first;
   while(next) {
      printf("%s\t%d\n",next->info.name, next->info.size);
      next = next->next;
   }
} 
Important functions are "_findfirst/_findnext".
Specfiy attributes about "file" in "struct _finddata_t info" using attrib.
User avatar
Spacebeard
Padawan Learner
Posts: 473
Joined: 2005-03-21 10:52pm
Location: MD, USA

Post by Spacebeard »

Antares wrote:

Code: Select all


   strcpy((char*)buf,env);
   strcat((char*)buf,"\\*.*");
  
This is a textbook example of code vulnerable to a stack smashing attack, by the way. I realize this was intended as a quick demonstration, but still, you'd want to do:

Code: Select all

strlcpy(buf, env, 1024);
strlcat(buf, "\\*.*", 1024);
(Or use strncpy() and strncat() on systems where the strl* functions don't exist).

Otherwise having the user set a DIR environment variable longer than 1024 characters will overflow the stack.

The casts are unnecessary, also.

Your example is also for DOS/Windows, while the OP specificed UNIX. This is an example of the use of opendir(), readdir(), and closedir() taken directly from the Solaris manual page for readdir(3c):

Code: Select all

     #include <sys/types.h>
     #include <dirent.h>
     #include <errno.h>
     #include <stdio.h>
     #include <strings.h>

     static void lookup(const char *arg)
     {
             DIR *dirp;
             struct dirent *dp;

             if ((dirp = opendir(".")) == NULL) {
                     perror("couldn't open '.'");
                     return;
             }

             do {
                     errno = 0;
                     if ((dp = readdir(dirp)) != NULL) {
                             if (strcmp(dp->d_name, arg) != 0)
                                     continue;

                             (void) printf("found %s\n", arg);
                             (void) closedir(dirp);
                             return;
                     }
             } while (dp != NULL);

             if (errno != 0)
                     perror("error reading directory");
             else
                     (void) printf("failed to find %s\n", arg);
             (void) closedir(dirp);
             return;
     }

     int main(int argc, char *argv[])
     {
             int i;
             for (i = 1; i < argc; i++)
                     lookup(argv[i]);
             return (0);
     }
That program will search the current working directory for files named in the command line arguments.
"This war, all around us, is being fought over the very meanings of words." - Chad, Deus Ex
Miles Teg
Padawan Learner
Posts: 300
Joined: 2002-07-21 06:11pm

Post by Miles Teg »

Thanks for the help! I ended up using C's opendir() et al.

I've learned in the last few days that I am *very* spoiled by Java when it comes to library functions! In Java what I am trying to accomplish (the heart of the problem anyway, ignoring error checking, etc.) is one line of code using the API:

File[] dirList = new File("/blah").listFiles();

I have a lot to learn with C/C++ it seems =)

Miles Teg
Now I am become death -- the shatterer of worlds...
-- Oppenheimer 1945
Post Reply