Here's a boost lambda functions version. This is overkill, and pretty cryptic, but it's brief and flexible in terms of how one can juggle with different fields criteria. Obviously you need boost. Also, expect increased compilation time. So, here it is:
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
#include "boost/lambda/detail/operator_actions.hpp"
#include "boost/lambda/detail/operator_return_type_traits.hpp"
#include "boost/lambda/detail/control_structures_impl.hpp"
#include "boost/ref.hpp"
#include <iostream>
#include <vector>
#include <string>
#include <iterator>
#include <algorithm>
#include <cassert>
using namespace std;
using namespace boost::lambda;
//helpers: a better way would be to group them
//under a flyweight, or something...
string extract_year(string str_)
{
return str_.substr(0,2);
}
string extract_dayofyear(string str_)
{
return str_.substr(2,3);
}
string extract_timeofday(string str_)
{
return str_.substr(5,4);
}
string extract_zone(string str_)
{
return str_.substr(10,1);
}
string extract_site(string str_)
{
return str_.substr(12,4);
}
//Uhm, just for brevity... ('cause otherwise we should stay away from macros ;-)
#define IF_THEN_ELSE_RET(op1,op2,exp) if_then_else_return(var(op1)<var(op2),true,if_then_else_return(var(op1)>var(op2),false,exp))
void sort_fnames(vector<string>& fnames)
{
string z1,z2,s1,s2,y1,y2,d1,d2,t1,t2;
//sort by zone-then-site-then-year-then-day-then-time:
//Note the format of the sort(fnames.begin(),fnames.end(), (,...,boolean_expression) );
//remember, in a sequence of comma-dellimited statements enclosed between parens, like
//val=(.,...,boolean_expression); only the last expression, boolean_expression, gets
//assigned to variable "val";
//So, in the sort() call below, the statements
//var(z1)=bind(extract_zone,_1),var(z2)=bind(extract_zone,_2), etc.
//are only initializing variables that are to be used in the composition
//of if_then_else_return(,,) lambda expressions whose composition
//combines the zone-then-site-then-year-then-day-then-time criteria
//and amounts to a boolean that is used by sort to decide the ordering
sort(fnames.begin(),fnames.end(),
(var(z1)=bind(extract_zone,_1),var(z2)=bind(extract_zone,_2),
var(s1)=bind(extract_site,_1),var(s2)=bind(extract_site,_2),
var(y1)=bind(extract_year,_1),var(y2)=bind(extract_year,_2),
var(d1)=bind(extract_dayofyear,_1),var(d2)=bind(extract_dayofyear,_2),
var(t1)=bind(extract_timeofday,_1),var(t2)=bind(extract_timeofday,_2),
IF_THEN_ELSE_RET(z1,z2,IF_THEN_ELSE_RET(s1,s2,IF_THEN_ELSE_RET(y1,y2,IF_THEN_ELSE_RET(d1,d2,IF_THEN_ELSE_RET(t1,t2,true)))))
));
}