python os.walk模块_[WIN32|STL]C++实现python的os模块的walk函数

[C++] 纯文本查看 复制代码/***************************************************

* 作者: 小冰

* 邮箱: [email]lovingxiaobing@qq.com[/email]

* 备注: [C++] 遍历目录的结果保存到STL容器中

* 函数的功能类似Python的os模块的walk函数

***************************************************/

#ifndef UNICODE

#define UNICODE

#endif

#ifndef _UNICODE

#define _UNICODE

#endif

#include

#include

#include

#include

#include

#include

#include

#if defined(UNICODE) || defined(_UNICODE)

#define str std::wstring

#define get_input(value) std::wcin>>value

#else

#define str std::string

#define get_input(value) std::cin>>value

#endif

using std::endl;

using std::list;

using std::tuple;

using std::make_tuple;

using std::for_each;

typedef tuple,list> walk_list_element_type;

typedef list walk_list;

void walk( str& path, walk_list& rtn_list, bool topdown=true ) {

DWORD dwFileAttr = GetFileAttributes(path.c_str());

if ( INVALID_FILE_ATTRIBUTES != dwFileAttr ) {

/// 只有是目录才遍历

if ( (FILE_ATTRIBUTE_DIRECTORY & dwFileAttr) == FILE_ATTRIBUTE_DIRECTORY ) {

WIN32_FIND_DATA wfd;

/// 开始搜索

HANDLE handle = FindFirstFile((path + str(_T("\\*"))).c_str(), &wfd);

if ( INVALID_HANDLE_VALUE != handle ) {

size_t times = 2;

str _path_file = path + str(_T("\\"));

list directorys;

list files;

/// 搜索下一个

while ( FindNextFile(handle, &wfd) ) {

str name = str(wfd.cFileName);

if ( (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY ) {

// 每个目录中只有一个 . 和 .. 目录, 过滤完了2次也就完了

// 还有一个问题就是如果目录很多,数量可以达到size_t所能容大的数的大小也没关系

// 因为即使那么多目录,也就使用2次lstrcmp,再次重新进入下一轮的--,所以忽略不计

// 总比一直调用函数效率高!

if ( times-- ) {

if ( !lstrcmp(wfd.cFileName, _T(".")) || !lstrcmp(wfd.cFileName, _T("..")) )

continue;

}

if ( topdown )

directorys.push_front(name);

else

directorys.push_back(name);

str _dir_entry(_path_file + name);

// 进入目录再次遍历

walk(_dir_entry, rtn_list);

}

else {

files.push_back(name);

}

}

if ( topdown )

rtn_list.push_front(make_tuple(path, directorys, files));

else

rtn_list.push_back(make_tuple(path, directorys, files));

FindClose(handle);

}

}

}

return;

}

// 格式化输出结果

void format_result( walk_list& res ) {

HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);

WriteConsole(hStdOut, _T("["), 1, NULL, NULL);

// 输出字符串

auto f_print_str = [&](str& s)->void {

WriteConsole(hStdOut, _T("\""), 1, NULL, NULL);

WriteConsole(hStdOut, s.c_str(), s.length(), NULL, NULL);

WriteConsole(hStdOut, _T("\""), 1, NULL, NULL);

};

// 输出列表元素

auto f_print_list = [&](list& v)->void {

WriteConsole(hStdOut, _T("["), 1, NULL, NULL);

for_each(v.begin(), v.end(),

[&](str& s)->void{f_print_str(s);

WriteConsole(hStdOut, _T(","), 1, NULL, NULL);});

WriteConsole(hStdOut, _T("]"), 1, NULL, NULL);

};

// 输出元组元素

auto f_print_tuple = [&](walk_list_element_type& v)->void {

WriteConsole(hStdOut, _T("("), 1, NULL, NULL);

// 输出目录

f_print_str(std::get<0>(v));

WriteConsole(hStdOut, _T(","), 1, NULL, NULL);

// 输出子目录

f_print_list(std::get<1>(v));

WriteConsole(hStdOut, _T(","), 1, NULL, NULL);

// 输出目录下的子文件

f_print_list(std::get<2>(v));

WriteConsole(hStdOut, _T(")"), 1, NULL, NULL);

};

// 遍历walk_list列表

for_each(res.begin(), res.end(),

[&](walk_list_element_type& v)->void{f_print_tuple(v);

WriteConsole(hStdOut, _T(",\n"), 2, NULL, NULL);});

WriteConsole(hStdOut, _T("]"), 1, NULL, NULL);

return;

}

int main( int argc, char* argv[] ) {

str note(_T("输入要遍历的目录(量力而行): "));

WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), note.c_str(), note.length(), NULL, NULL);

str path;

get_input(path);

// 规范输入的路径

for ( auto it = path.begin(); it != path.end(); ++it ) {

if ( *it == '/' ) {

*it = '\\';

}

}

while ( path.back() == '\\' )

path.pop_back();

// 将"."转换成当前运行路径

if ( path.length() == 1 && path[0] == '.' ) {

TCHAR buf[MAX_PATH];

GetCurrentDirectory(MAX_PATH, buf);

path = str(buf);

}

/// 用来接收结果

walk_list rtn;

walk(path, rtn, true);

format_result(rtn);

WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), _T("\n"), 1, NULL, NULL);

system("pause");

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值