2010-05-11 93 views
3

如何實現ls「filename_ [0-5] [3-4]?」喜歡上課嗎?我想存儲在矢量中的結果。C++模仿命令ls

目前我使用系統()這是調用LS,但這並不是MS下便攜。

謝謝, Arman。

+0

這是一個glob模式嗎?該模式的部分'[4-3]'可能不會達到您的預期。它的計算結果是文字'[4-3]',所以你的意思是'[3-4]'這意味着3或4. – wilhelmtell 2010-05-11 08:27:43

+0

哦,是的,真的對不起我的壞。 – Arman 2010-05-11 08:29:55

+0

我不知道'ls'如何類似__class .__對我來說,它似乎更像是一種算法,因此是一種功能。 – sbi 2010-05-11 08:35:51

回答

5

下面的程序將列出文件在當前目錄名稱的正則表達式匹配filename_[0-5][34]

#include <boost/filesystem.hpp> 
#include <boost/regex.hpp> // also functional,iostream,iterator,string 
namespace bfs = boost::filesystem; 

struct match : public std::unary_function<bfs::directory_entry,bool> { 
    bool operator()(const bfs::directory_entry& d) const { 
     const std::string pat("filename_[0-5][34]"); 
     std::string fn(d.filename()); 
     return boost::regex_match(fn.begin(), fn.end(), boost::regex(pat)); 
    } 
}; 

int main(int argc, char* argv[]) 
{ 
    transform_if(bfs::directory_iterator("."), bfs::directory_iterator(), 
       std::ostream_iterator<std::string>(std::cout, "\n"), 
       match(), 
       mem_fun_ref(&bfs::directory_entry::filename)); 
    return 0; 
} 

我省略transform_if()定義爲簡潔。這不是一個標準功能,但應該直接實施。

+0

當你嘗試編譯這個時,記得在註釋中添加缺少的'#include',定義缺少的'transform_if()'(如果需要的話,我可以給你一個手),並鏈接到文件系統和正則表達式庫。使用g ++,您可以通過在命令行中指定「-lboost_filesystem -lboost_system -lboost_regex」來鏈接這些庫。如果你在Linux上,你可能不需要'-lboost_system'標誌。 – wilhelmtell 2010-05-11 10:14:46

+0

這太不可思議了!適用於Linux和MS。謝謝! 順便說一句:所述transform_if我使用這樣的: 模板<類在,類輸出,類潑尼鬆,類運算> 缺貨transform_if(在第一,在最後,輸出RES,潑尼鬆P,運算運算) \t { \t而(第一!=(last)){ \t \t if(p(* first)) \t \t \t * res = op(* first); \t \t ++第一個; ++ res; \t \t} \t return res; \t} – Arman 2010-05-11 12:05:15

+0

@阿曼是的,看起來不錯! – wilhelmtell 2010-05-11 12:07:48

2

您可以使用boost :: filesystem,它有一種可移植的方式來檢索目錄中的文件。

然後你可以用boost :: regex檢查文件的正則表達式,例如只保留與你的模式匹配的文件。

+0

謝謝,我不熟悉正則表達式,請給我一個解析我的模式的例子嗎? – Arman 2010-05-11 08:22:46

+1

你可以查看來自boost的文檔:http://www.boost.org/doc/libs/1_43_0/libs/regex/doc/html/boost_regex/syntax/perl_syntax.html 據我記得,它會與「filename_ [0-5] [3-4]」不同「 – Nikko 2010-05-11 08:39:13

+0

這個glob模式恰好也是一個正則表達式,事實如此。你可以改變'[3-4]'到'[34]'並保持相同的含義,但除此之外它保持不變。 – wilhelmtell 2010-05-11 09:15:33

0

升壓解決方案是便攜式的,但在Windows上不是最佳的。原因是它調用FindFirstFile("*.*")並返回所有內容。鑑於globbing模式,調用FindFirstFile("filename_?*.*")會更有效。您仍然需要過濾結果(例如使用Boost :: regex),但這會排除許多無法匹配的文件。

此外,使用任一方法不要忘記在進行正則表達式匹配之前過濾掉目錄。檢查一個條目是否是一個目錄是相當便宜的。

+0

真的嗎?即使使用'boost :: filesystem :: directory_iterator'?我可以看到OS X上的情況並非如此。 – wilhelmtell 2010-05-11 10:05:25

+0

我可能誤解了你的評論,但我不明白爲什麼OSX很重要,因爲我解釋了Windows上的Boost不是最優的。 – MSalters 2010-05-11 11:36:40

+0

我並沒有反駁你。我剛剛說過,OS X上的情況並非如此。寒意。 – wilhelmtell 2010-05-11 12:05:39