c语言实现dos命令dir dir/s 目录遍历

代码如下:

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.txt
2007-10-25  18:06                40 filename.txt
2007-11-09  01:01               192 main.c
2007-11-09  01:01            19,971 main.exe
2007-10-20  19:55               574 main.o
2007-10-20  19:55               764 Makefile.win
2007-10-20  19:55               823 test.dev
2007-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.txt
2007-10-25  18:06                40 filename.txt
2007-11-09  01:01               192 main.c
2007-11-09  01:01            19,971 main.exe
2007-10-20  19:55               574 main.o
2007-10-20  19:55               764 Makefile.win
2007-10-20  19:55               823 test.dev
2007-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
}

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值