C++ 中目录文件名的自然排序 [英] Natural Sort of Directory Filenames in C++
问题描述
我有一个目录列表,我想检索文件名并将它们放入字符串向量中,以便它们以自然"方式排序.例如{ "10.txt" "0.txt" "2.txt" "1.m" "Jan12" "July13.txt" "Nov25.txt" "Jane" "John" }
{"0.txt" "1.m" "2.txt" "10.txt" "Jan12" "July13.txt" "Nov25.txt" "Jane" "John" }
.最简单的方法是什么?
I have a directory listing for which I want to retrieve the filenames and put them in a vector of strings such that they are sorted in a "natural" manner. e.g. { "10.txt" "0.txt" "2.txt" "1.m" "Jan12" "July13.txt" "Nov25.txt" "Jane" "John" }
should be {"0.txt" "1.m" "2.txt" "10.txt" "Jan12" "July13.txt" "Nov25.txt" "Jane" "John" }
. What is the easiest way to do this?
详细说明自然",我们假设一个字符串由部分数字 (N) 和文本 (T) 组成,这样 ...(N)(T)...
,然后对于 ...(N1)(T1)...
和 ...(N2)(T2)...
将是 (N1
(<)
意味着左项优先于右项.在这种情况下,如果数字在字符串中处于相同位置,则数字优先于文本字段,即 1.z (<) 1_t.txt
.
Elaborating on "natural" we assume for a string made up from parts of numbers (N) and text (T) such that ...(N)(T)...
, then for ...(N1)(T1)...
and ...(N2)(T2)...
will be (N1<N2) (<) (T1<T2)
where (<)
implies left term precedence over right term. In this case, numbers take precedence over text fields if they are in the same position in the string, i.e. 1.z (<) 1_t.txt
.
是否已经有一个库函数可以对字母数字字符串或目录条目进行这种排序?
Is there already a library function to do that kind of sort for alphanumeric strings, or directory entries?
所需的顺序 文件应该出现的顺序.文件名将存储在字符串向量中.
DESIRED order in which files should come. The file names will be stored in a vector of strings.
Abhinav@Abhinav-PC /cygdrive/c/AbhinavSamples/shell
$ ls -lv
total 8
-rw-r--r--+ 1 Abhinav None 2 Mar 17 00:51 1.txt
-rw-r--r--+ 1 Abhinav None 2 Mar 17 00:55 1_t.txt
-rw-r--r--+ 1 Abhinav None 2 Mar 17 00:50 3.txt
-rw-r--r--+ 1 Abhinav None 2 Mar 17 00:51 4.txt
-rw-r--r--+ 1 Abhinav None 2 Mar 17 00:53 10.txt
-rw-r--r--+ 1 Abhinav None 2 Mar 17 00:56 10_t.txt
-rw-r--r--+ 1 Abhinav None 2 Mar 17 00:56 13.txt
-rw-r--r--+ 1 Abhinav None 2 Mar 17 00:53 20.txt
**Simple Sort**
Abhi@Abhi-PC /cygdrive/c/AbhinavSamples/shell
$ ls -l
total 8
-rw-r--r--+ 1 Abhinav None 2 Mar 17 00:51 1.txt
-rw-r--r--+ 1 Abhinav None 2 Mar 17 00:53 10.txt
-rw-r--r--+ 1 Abhinav None 2 Mar 17 00:56 10_t.txt
-rw-r--r--+ 1 Abhinav None 2 Mar 17 00:56 13.txt
-rw-r--r--+ 1 Abhinav None 2 Mar 17 00:55 1_t.txt
-rw-r--r--+ 1 Abhinav None 2 Mar 17 00:53 20.txt
-rw-r--r--+ 1 Abhinav None 2 Mar 17 00:50 3.txt
-rw-r--r--+ 1 Abhinav None 2 Mar 17 00:51 4.txt
推荐答案
glibc 中有一个函数可以完全满足您的需求.不幸的是,它是 C,而不是 C++,所以如果你能接受,这里是最简单的开箱即用"解决方案,无需重新实现任何东西并重新发明轮子.顺便说一句:这与 ls -lv
的实现完全一样.其中最重要的部分是 versionsort
函数,它为您执行自然排序.它在这里用作 scandir
的比较函数.下面的简单示例打印当前目录中的所有文件/目录,按您的意愿排序.
There is a function that does exactly what you want in glibc. Unfortunately it is C, not C++, so if you can live with that here is the simplest possible solution "out of the box", without reimplementing anything and reinventing the wheel. BTW: this is exactly as ls -lv
is implemented. The most important part of it is the versionsort
function which does the natural sort for you. It is used here as a comparison function for scandir
.
The simple example below prints all files/directories in current directory sorted as you wish.
#define _GNU_SOURCE
#include <dirent.h>
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
struct dirent **namelist;
int n,i;
n = scandir(".", &namelist, 0, versionsort);
if (n < 0)
perror("scandir");
else
{
for(i =0 ; i < n; ++i)
{
printf("%s
", namelist[i]->d_name);
free(namelist[i]);
}
free(namelist);
}
return 0;
}
这篇关于C++ 中目录文件名的自然排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!