2016-06-21 58 views
0

我有一个程序,输入需要的文件列表,这是保存在std::vector删除重复的文件名

std::vector<std::string> fileNames; 

用户完全可以自由进入任何文件名(他们采取从argv),并且如果其进入是指同一文件的程序应该忽略重复项的文件名。 的问题是,用户甚至可以使具有矢量是这样的:

{ 
"myfile1.txt", 
"/path/to/myfile1.txt", 
"/path//to/myfile1.txt" 
} 

考虑我从/path/to调用程序,这三个文件的名字指的是同一个文件,但它们是不同的字符串。

我必须打开它们fopen()不是std::ifstream)。

,并检查他们所有的程序fopen() S中所有文件开始的过程之前,所以它不是一个问题。

是否有删除重复的文件名称的有效途径?

+2

你为什么不给我们一套? –

+2

第一步是将它们归一化为相同的形式:完整路径,更换''//用'/'然后它的一个简单的任务 – vu1p3n0x

+1

[可能有助于](http://www.boost.org/doc/libs /1_48_0/libs/filesystem/v3/doc/reference.html#canonical)。请注意,该路径必须存在才能起作用,并且“if(exists){...}”不够好,因为它在您使用它时可能不存在。 – chris

回答

2

您可以使用std::set,而不是一个向量,以确保相同的字符串只列出一次。

或者,也可以std::sort(或std::stable_sort)的向量,然后使用与std::uniquestd::erase组合以删除重复。

至于那指代相同的文件不相同的字符串;在Linux上,您可以使用realpath(3)在将所有路径添加到向量(或集合)之前对其进行规范化。我不知道Windows上的等效函数,但我确定有一个。如果你还需要在Windows上工作,也许可以尝试通过msdn.com搜索。

+0

该集会保持用户给定的文件的顺序吗? – NoImaginationGuy

+0

@ osnapitzkindle编号该套件不会保留该订单。 –

+0

是不是有一个有序的集或类似许多其他语言的东西? – NoImaginationGuy

0

对于便携式解决方案,您可以使用boost::filesystem

boost::equivalent()

返回:true,如果SF1 == SF2和p1和p2解析为同一个文件系统 实体,否则为假。

这种方式,你将不得不每个文件比较VS对方,或者您可以使用boost::canonical()boost::weekly_canonical()正常化的路径和使用std::sort这可能是更有效,因为它不具备比较每对。