user2003965
user2003965

Reputation: 503

Sorting files with boost filesystem

here is my problem: I got a stack of files that have names like "_X1.bla.txt", "_X101.bla.txt", _X47.bla.txt" that i read in with boost::filesystem and added to a std::vector .

As you see from the example, the names do not start with the numbers. In this example, the result shoud be 1, 47, 101. If you got tell me how i could extract the numbers from the files i should be able to autosort the files by myself.

Best hu dao

Upvotes: 4

Views: 4311

Answers (3)

Raxvan
Raxvan

Reputation: 6505

If you have all the names in a container (something like std::vector filenames) you can do

std::sort(filenames.begin(),filenames.end()) 

and it will use the default sorting function. If you want a custom one you can do:

struct sort_functor
{
    bool operator ()(const std::string & a,const std::string & b)
    {
        return a < b;// or some custom code
    }
};
void test()
{
    std::vector<std::string> filenames;
    std::sort(filenames.begin(),filenames.end(),sort_functor());
}

Upvotes: 4

P0W
P0W

Reputation: 47814

You can use boost::regex to extract number as string, convert the string to number in a custom comparator for std::sort to sort the std::vector of your files

boost::regex re("(\\d+)");
boost::match_results<std::string::const_iterator> what1,what2;

template <typename T>
T st2num ( const std::string &Text )
{
     std::stringstream ss(Text);
     T result;
     return ss >> result ? result : 0;
}
struct mysort
{
    bool operator ()(const std::string & a,const std::string & b) 
    {

    boost::regex_search(a.cbegin(), a.cend(), what1, re,
                           boost::match_default);
    boost::regex_search(b.cbegin(), b.cend(), what2, re,
                           boost::match_default);

    return st2num<int>(what1[1]) < st2num<int>(what2[1]);

    }
};

And then,

//std::vector<std::string> vec{"_X1.bla.txt", "_X101.bla.txt", "_X47.bla.txt"}; std::sort( vec.begin() , vec.end() ,mysort() );

Upvotes: 3

alexbuisson
alexbuisson

Reputation: 8469

let suppose that you have used boost filesystem directory_iterator. With an iterator you have access to the filename as a string.

Use a regex (\d+) to extract the number (if more than one)

and instead of using a 'vector of pair (int , string)' you can use directly an ordered map.

Upvotes: 0

Related Questions