вы можете использовать std :: sort, разделяя ваши имена файлов на число + строку (оба необязательные).
#include <vector>
#include <string>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <cstring>
using namespace std;
bool compare_filenames(string a, string b)
{
char *pA, *pB;
long A = strtol(a.c_str(), &pA, 10),
B = strtol(b.c_str(), &pB, 10);
if (A < B)
return true;
if (A == B)
return strcmp(pA, pB);
return false;
}
int main_compare_filenames(int, char **)
{
const char *v[] ={
"1.txt",
"10.txt",
"10_t.txt",
"13.txt",
"1_t.txt",
"20.txt",
"3.txt",
"4.txt"
};
vector<string> t(v, v + 8);
sort(t.begin(), t.end(), compare_filenames);
copy(t.begin(), t.end(), ostream_iterator<string>(cout, "\n"));
return 0;
}
выход:
1_t.txt
1.txt
3.txt
4.txt
10_t.txt
10.txt
13.txt
20.txt
Это почти работает, но есть проблема, заключающаяся в том, что '_' предшествует '.', Поэтому требуется дополнительная настройка:
string remove_dot(const char *p)
{
const char *dot = strchr(p, '.');
return dot ? string(p, dot - p) : string(p);
}
bool compare_filenames(string a, string b)
{
char *pA, *pB;
long A = strtol(a.c_str(), &pA, 10),
B = strtol(b.c_str(), &pB, 10);
if (A < B)
return true;
if (A == B)
return remove_dot(pA) < remove_dot(pB);
return false;
}
выход: * +1010 *
1.txt
1_t.txt
3.txt
4.txt
10.txt
10_t.txt
13.txt
20.txt