开发者

reading a directory in C++ in portable way

I have a requirement as follows. I have a directory for eg i have /tmp/myFolder

开发者_StackOverflow社区

Under "myFolder" i have files whose names as below

myFile-N001.txt
myFile-N002.txt
myFile-N003.txt

in my application while writing to a file i should write to largest number file in /tmp/myFolder, for eg in above case i should write to myFile-N003.txt.

The above should be achieved in C++ and in portable way preferably in POSIX way.

Can any one provide simple example on how we can achive this in C++.

Thanks


If you are happy enough to:

  • work only on POSIX
  • You know the pattern you are looking for

You can use the glob() function in POSIX to get the list.

You can then use std::max with a custom comparison on the result set with your iterator range being globres.gl_pathv[0], globres.gl_pathv[globres.gl_pathc] and a comparison being something like:

bool strless(const char* str1, const char* str2 )
{
   return strcmp( str1, str2 ) < 0;
}

although there is most likely something already that does that

The start of the "man" page for glob:

   #include <glob.h>

   int glob(const char *pattern, int flags,
            int (*errfunc) (const char *epath, int eerrno),
            glob_t *pglob);

   void globfree(glob_t *pglob);

DESCRIPTION

The glob() function searches for all the pathnames matching pattern according to the rules used by the shell (see glob(7)). No tilde expansion or parameter substitution is done; if you want these, use wordexp(3).

The globfree() function frees the dynamically allocated storage from an earlier call to glob().

The results of a glob() call are stored in the structure pointed to by pglob. This structure is of type glob_t (declared in <glob.h>) and includes the following elements defined by POSIX.2 (more may be present as an extension):

 typedef struct 
 {
     size_t   gl_pathc;    /* Count of paths matched so far  */
     char   **gl_pathv;    /* List of matched pathnames.  */
     size_t   gl_offs;     /* Slots to reserve in gl_pathv.  */
 } glob_t;

There was a discussion in October 2004 about bringing glob into boost I don't think it ever got implemented:


There's code for retrieving the list of files from a directory in a POSIX-compliant way here.

You could build on that by sorting the resulting array and popping the last element off. That would be the file you want to find.


This is really two problems in one. I'd use Boost.Filesystem to portably iterate over the files and store them in a vector with (untested)

std::string maxname;
unsigned maxnum = 0;

for (fs::path::iterator i(dir.begin()), end(dir.end()); i != end; ++i) {
    std::string name = i->string();
    unsigned num;
    if (std::sscanf(name.c_str(), "myFile-N%u.txt", &num) == 1
     && num >= maxnum) {
        maxnum = num;
        maxname = name;
    }
}

then check whether maxname holds the empty string after the loop. If it doesn't, it holds the filename you want.


You can use boost::filesystem to achieve this.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜