代码如下: v0.3 没有实现/s的功能 /**/ /*版权说明:代码原创 转载保留 随意使用 程序名称:c语言实现dos命令dir dir/s问题出处:学编程论坛 c语言版块 http://www.xuebc.com 代码作者:老岩 论坛id:luntanybb作者博客:http://hi.baidu.com/ybbmdf 作者邮件:shuaishuainanying#qq.com 编译环境:dev-c++ 4.9.9.2 windows xp sp2文件类型:.c文件 版本编号:v0.5版本说明:基本完成 /s功能没有时间 待续 代码函数详解: http://hi.baidu.com/ybbmdf/blog/item/b4447c314a3c171aebc4af90.html代码首发地址: http://blog.csdn.net/ybbmdf/archive/2007/11/14/1885703.aspx程序演示地址: http://hi.baidu.com/ybbmdf/blog/item/b4447c314a3c171aebc4af90.html此版本编译后exe文件下载地址:http://gabmyd.ys168.com/ (名称:test_dir_ok.exe) */ /**/ /*注:这段代码是很早以前写的,因为有朋友询问,所以整理一下,为了朋友们能很好的理解这段代码,我又加了很多注释,此代码中非常用函数较多,所以把函数的一些原型解释等放到博客中详细解答,地址在上面查找。 此代码是c代码,非c++,但有些特性需要c99支持,请尽量使用dev,其他环境没有调试,我想需要这方面资料的人很多,所以做的很细,大家应该很容易理解有问题欢迎来信,或到访博客。 显示结果中文件大小的","、分卷号的"-" 没有处理,大家加代码吧,不难,我就不写了。其它完全安装dir命令的结果格式调试。 */ #include < stdio.h > #include < stdlib.h > #include < time.h > #include < io.h > #include < string .h > #include < windows.h > void nonce( int ); int main( int argc, char * argv[]) ... { if (argv[1] == '/s') ...{ /**//*递归*/ } else ...{ nonce(0); } getchar();/**//*启 停屏作用*/ return 0; } /**/ /*函数功能:dir当前目录 参数:on_off是否参加/s 参数值:0-不参加 1-第一次目录显示 2-一次以上目录显示模块开发:luntanybb */ void nonce( int on_off) ... { int i;/**//*循环变量*/ int file=0, dir=0;/**//*文件总数 子目录总数*/ long p;/**//*查找文件的句柄*/ struct _finddata_t f;/**//*查找文件的结果数据*/ struct tm *ti=NULL;/**//*本地化时间*/ char volume_name[256]; /**//*卷标*/ char t[20]="", prompt[10]="";/**//*要输出的时间 文件类型提示信息*/ char buffer[_MAX_PATH];/**//*当前路径*/ char tree_dir[5]="c:/";/**//*跟目录*/ unsigned long volume_number;/**//*卷区序列号*/ int64_t sum_z=0;/**//*本目录文件大小总和*/ int64_t l_user, l_sum, l_idle;/**//*用户可用空间 已使用空间 剩余空间*//**//*显示如 下所示内容: 驱动器 I 中的卷是 实验室 卷的序列号是 2C59-A214 I:c 的目录 */ getcwd(buffer, _MAX_PATH);/**//*得到当前目录*/ tree_dir[0]=buffer[0];/**//*提取系统盘符*/ /**//*取得卷区信息*/ GetVolumeInformation(tree_dir,volume_name,50,&volume_number,NULL,NULL,NULL,10); printf(" 驱动器 %c 中的卷是 %s ",tree_dir[0],volume_name); printf(" 卷的序列号是 %X ",volume_number); printf(" %s 的目录 ",buffer);/**//*显示当前目录*/ /**//*显示如 下所示内容: 2007-11-14 00:39 <DIR> .2007-11-14 00:39 <DIR> ..2007-11-10 14:48 460 axa.txt2007-10-25 18:06 40 filename.txt2007-11-09 01:01 192 main.c2007-11-09 01:01 19,971 main.exe2007-10-20 19:55 574 main.o2007-10-20 19:55 764 Makefile.win2007-10-20 19:55 823 test.dev2007-10-20 19:55 15,663 test.exe*/ p = _findfirst("*.*", &f);/**//*查找文件*/ if (p == -1) ...{ printf("以外错误 程序结束! "); exit(-1);/**//*以外错误 程序结束*/ } do ...{ /**//*找到的文件最后一次修改日历时间改为本地时间*/ ti = localtime(&f.time_write); strftime(t,20,"%Y-%m-%d %H:%M",ti);/**//*按照格式显示日期时间*/ if (_A_SUBDIR == f.attrib)/**//*判断是不是目录*/ ...{ strcpy(prompt," <DIR>");/**//*提示内容*/ dir++;/**//*目录个数 */ } else ...{ strcpy(prompt," ");/**//*提示内容*/ file++;/**//*文件个数 */ } printf("%s%s",t,prompt);/**//*显示文件最后修改时间 和目录与否*/ if (_A_SUBDIR != f.attrib)/**//*判断是不是目录*/ printf("%9lu",f.size);/**//*显示文件大小*/ else printf(" ");/**//*目录大小为0 dir命令不显示*/ printf(" %s ",f.name);/**//*显示文件名*/ sum_z += f.size;/**//*计算文件夹下文件大小总和*/ } while (!(_findnext(p,&f)));/**//*查找下一个 直到没有文件为止*/ _findclose(p);/**//*关闭搜索*/ /**//*显示如 下所示内容: 23 个文件 953,394 字节 3 个目录 6,633,803,776 可用字节*/ /**//*显示文件夹下文件总数 和大小总和*/ printf("%16d 个文件%15I64d 字节 ",file,sum_z); /**//*取得卷区空间容量信息 现在磁盘都很大所以放弃GetDiskFreeSpace函数*/ GetDiskFreeSpaceEx(tree_dir,(PULARGE_INTEGER)&l_user,(PULARGE_INTEGER)&l_sum,(PULARGE_INTEGER)&l_idle); /**//*显示文件夹下子文件的数量 分区可用空间*/ printf("%16d 个目录%15I64d 可用字节 ",dir,l_idle); } v0.5实现/s功能 /**/ /*版权说明:代码原创 转载保留 随意使用 程序名称:c语言实现dos命令dir dir/s问题出处:学编程论坛 c语言版块 http://www.xuebc.com 代码作者:老岩 论坛id:luntanybb作者博客:http://hi.baidu.com/ybbmdf 作者邮件:shuaishuainanying#qq.com 编译环境:dev-c++ 4.9.9.2 windows xp sp2文件类型:.c文件 版本编号:v0.5版本说明:基本完成 /s功能没有时间 待续 代码函数详解: http://hi.baidu.com/ybbmdf/blog/item/b4447c314a3c171aebc4af90.html代码首发地址: http://blog.csdn.net/ybbmdf/archive/2007/11/14/1885703.aspx程序演示地址: http://hi.baidu.com/ybbmdf/blog/item/b4447c314a3c171aebc4af90.html此版本编译后exe文件下载地址:http://gabmyd.ys168.com/ (名称:test_dir_ok.exe) */ /**/ /*注:这段代码是很早以前写的,因为有朋友询问,所以整理一下,为了朋友们能很好的理解这段代码,我又加了很多注释,此代码中非常用函数较多,所以把函数的一些原型解释等放到博客中详细解答,地址在上面查找。 此代码是c代码,非c++,但有些特性需要c99支持,请尽量使用dev,其他环境没有调试,我想需要这方面资料的人很多,所以做的很细,大家应该很容易理解有问题欢迎来信,或到访博客。 显示结果中文件大小的","、分卷号的"-" 没有处理,大家加代码吧,不难,我就不写了。其它完全安装dir命令的结果格式调试。 */ /**/ /**********************************************************************/ /**/ /*应朋友要求 继续完善此程序0.5版实现了/s的功能缺陷,与0.3相同 dir命令dir/s命令的显示 是有选择的 dir隐藏文件和系统文件都不显示的而我做的没有处理 一律都显示了dir/s命令统计隐藏文件信息 可能还包括其他信息 我没有研究呢~有需要的话下一个版本改进0.5版的显示格式完全按照dir命令显示格式一致了 关于编译器请使用dev-c++ 4.9.9.2 如使用vc6.0或者vs2005等 请吧int64_t改成__int64但是还有有别的问题如得到当前路径等 跟这个代码不一样 具体的可以查msdn来找。我就不找了 按照错误提示换几个系统函数就行 dev网站:http://www.bloodshed.net/ 推荐dev来编c语言 或者c++ 应为它支持最新的c99;ISO.IEC 14882.2003标准 可能不是完全但是是支持特性最多的。再有就是收费的软件了。 如想像dir那样在那个目录都能用 请把这个程序添加到 环境变量里就可以了 此版本编译后exe文件下载地址:http://gabmyd.ys168.com/ (名称:dir-s_1.exe) 演示地址: http://hi.baidu.com/ybbmdf/blog/item/b4447c314a3c171aebc4af90.html*/ #include < stdio.h > #include < stdlib.h > #include < time.h > #include < io.h > #include < string .h > #include < windows.h > typedef struct /**/ /*目录下 数量总和*/ ... { int64_t f;/**//*文件总和*/ int64_t d;/**//*子目录总和*/ int64_t s;/**//*文件大小总和*/} num_sum; char buffer[_MAX_PATH]; /**/ /*起始目录路径*/ num_sum s_sum; /**/ /*dir/s形式统计总和*/ /**/ /*显示如 下所示内容: 驱动器 I 中的卷是 实验室 卷的序列号是 2C59-A214*/ /**/ /*功能:dir 上部信息 返回值:无 参数:无*/ void up( void ) ... { char tree_dir[5]="c:/";/**//*跟目录*/ char volume_name[256]; /**//*卷标*/ unsigned long volume_number;/**//*卷区序列号*/ getcwd(buffer, _MAX_PATH);/**//*得到当前目录*/ tree_dir[0]=buffer[0];/**//*提取系统盘符*/ /**//*取得卷区信息*/ GetVolumeInformation(tree_dir,volume_name,50,&volume_number,NULL,NULL,NULL,10); printf(" 驱动器 %c 中的卷是 %s ",tree_dir[0],volume_name); printf(" 卷的序列号是 %X ",volume_number); } /**/ /*显示如 下所示内容: I:c 的目录 2007-11-14 00:39 <DIR> .2007-11-14 00:39 <DIR> ..2007-11-10 14:48 460 axa.txt2007-10-25 18:06 40 filename.txt2007-11-09 01:01 192 main.c2007-11-09 01:01 19,971 main.exe2007-10-20 19:55 574 main.o2007-10-20 19:55 764 Makefile.win2007-10-20 19:55 823 test.dev2007-10-20 19:55 15,663 test.exe*/ /**/ /*功能:显示当前目录下 文件列表 返回值:此文件夹下数据总和统计参数:需要显示的目录 */ num_sum file_list( char pat[_MAX_PATH]) ... { num_sum x;/**//*此目录统计总和*/ long p;/**//*查找文件的句柄*/ struct _finddata_t f;/**//*查找文件的结果数据*/ struct tm *ti=NULL;/**//*本地化时间*/ char t[20]="", prompt[10]="";/**//*要输出的时间 文件类型提示信息*/ int64_t file=0, dir=0;/**//*文件总数 子目录总数*/ int64_t sum_z=0;/**//*本目录文件大小总和*/ printf(" %s 的目录 ",pat);/**//*显示当前目录*/ chdir(pat);/**//*变更当前目录*/ p = _findfirst("*.*", &f);/**//*查找文件*/ if (p == -1) ...{ printf("以外错误 程序结束! "); exit(-1);/**//*以外错误 程序结束*/ } do ...{ /**//*找到的文件最后一次修改日历时间改为本地时间*/ ti = localtime(&f.time_write); strftime(t,20,"%Y-%m-%d %H:%M",ti);/**//*按照格式显示日期时间*/ if (_A_SUBDIR == f.attrib)/**//*判断是不是目录*/ ...{ strcpy(prompt," <DIR>");/**//*提示内容*/ dir++;/**//*目录个数 */ } else ...{ strcpy(prompt," ");/**//*提示内容*/ file++;/**//*文件个数 */ } printf("%s%s",t,prompt);/**//*显示文件最后修改时间 和目录与否*/ if (_A_SUBDIR != f.attrib)/**//*判断是不是目录*/ printf("%9lu",f.size);/**//*显示文件大小*/ else printf(" ");/**//*目录大小为0 dir命令不显示*/ printf(" %s ",f.name);/**//*显示文件名*/ sum_z += f.size;/**//*计算文件夹下文件大小总和*/ } while (!(_findnext(p,&f)));/**//*查找下一个 直到没有文件为止*/ _findclose(p);/**//*关闭搜索*/ /**//*显示如 下所示内容: 23 个文件 953,394 字节*/ /**//*显示文件夹下文件总数 和大小总和*/ printf("%16I64d 个文件 %14I64d 字节 ",file,sum_z); x.f = file; x.d = dir; x.s = sum_z; return x;/**//*返回此文件夹下文件总和*/} /**/ /*显示如 下所示内容: 3 个目录 6,633,803,776 可用字节*/ /**/ /*功能:dir 下面信息 返回值: 无参数:一个目录下数量总和*/ void down(num_sum s) ... { int64_t l_user, l_sum, l_idle;/**//*用户可用空间 已使用空间 剩余空间*/ /**//*取得卷区空间容量信息 现在磁盘都很大所以放弃GetDiskFreeSpace函数*/ GetDiskFreeSpaceEx(buffer,(PULARGE_INTEGER)&l_user,(PULARGE_INTEGER)&l_sum,(PULARGE_INTEGER)&l_idle); /**//*显示文件夹下子文件的数量 分区可用空间*/ printf("%16I64d 个目录 %14I64d 可用字节 ",s.d,l_idle);} /**/ /*功能:显示/s方法显示文件列表返回值:无参数:列表目录 */ void bar_s( char pat[_MAX_PATH]) ... { long p;/**//*查找文件的句柄*/ struct _finddata_t f;/**//*查找文件的结果数据*/ num_sum z;/**//*一个目录下 数量总和*/ char pat_save[_MAX_PATH];/**//*用于保留当前层路径*/ strcpy(pat_save,pat);/**//*保留当前层路径*/ z = file_list(pat);/**//*显示文件夹当前列表*/ s_sum.f += z.f;/**//*/s down函数统计增加*/ s_sum.d += z.d; s_sum.s += z.s; p = _findfirst("*.*", &f);/**//*查找文件*/ if (p == -1) ...{ printf("以外错误 程序结束! "); exit(-1);/**//*以外错误 程序结束*/ } do ...{ if (_A_SUBDIR == f.attrib && ((strcmp(f.name,".") != 0) && (strcmp(f.name,"..") != 0)))//判断是不是目录 ...{ //递归调用显示文件列表 参数当前目录++子文件夹名 if (3 == strlen(pat))/**//*避免根目录下调用有 i:/***的问题*/ bar_s(strcat(pat,f.name)); else bar_s(strcat(strcat(pat,"/"),f.name)); //递归后回复 当前层路径 因为上条语句strcat是参数2追加到参数1 在返回参数1 //此过程中改变了参数1 所以需要改回来 strcpy(pat,pat_save); } } while (!(_findnext(p,&f)));/**//*查找下一个 直到没有文件为止*/ _findclose(p);/**//*关闭搜索*/} /**/ /*功能:显示/s功能最后的统计数据 返回值:无参数:无(调用全局变量s_sum) */ void down_s( void ) ... { printf(" 所列文件总数: %16I64d 个文件 %14I64d 字节 ",s_sum.f,s_sum.s); down(s_sum);} int main( int argc, char * argv[]) ... { if (argc == 1) ...{ //getcwd(pat, _MAX_PATH);/*得到当前目录*/ up(); down(file_list(buffer)); } else ...{ if (0 == strcmp(argv[1],"/s")) ...{ up(); bar_s(buffer); down_s(); } else ...{ printf("参数错误 "); } } getchar();/**//*启 停屏作用*/ return 0; }