经典错误,请高人帮忙分析-linux下统计当前目录下的子目录数(当前目录)与其各子目录下的文件数?

时间:2022-01-26 14:10:16
有目录结构:
./a/aa/aaa/1.txt
./a/aa/aaa/2.txt
./a/aa/aaa/3.txt

./a/aa/bbb/1.txt
./a/aa/bbb/2.txt
./a/aa/bbb/3.txt

./a/aa/ccc/1.txt
./a/aa/ccc/2.txt
./a/aa/ccc/3.txt


我用的实现while循环下加嵌套函数。
按上面目录结构输出正确结果应该为:文件数9个 目录数6

可我的程序结果为:文件数3个 目录数4个(bbb ccc2个目录及其下面的6个文件未统计)
完整代码如下:
#include <iostream>
using namespace std;
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
#include <sys/stat.h>
#include <string.h>

int Fn=0;
int Dn=0;
DIR* p_Dir = NULL;

int count(char *);

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

    if(argc!=2){
        cout <<"Usage:<filename> DirName"<<endl;
        return -1;
    }

    p_Dir = opendir(argv[1]);

    if(NULL==p_Dir){
        cout <<"Can't find the Dir:"<<argv[1]<<endl;
        return -2;
    }
    else{
        closedir(p_Dir);
    }
    p_Dir=NULL;

    count(argv[1]);//函授调用

    cout <<"The director include: "<<Fn<<" files and "<<Dn<<" directors."<<endl;
}

//函数定义
int count(char* s_dir){
    struct stat buf;
    struct dirent* p_Dirent = NULL;
    if(stat(s_dir,&buf)<0){
        cout << "stat error\n";
        return -2;
    }
    if(S_ISDIR(buf.st_mode)){
        if(NULL==(p_Dir = opendir(s_dir))){
            cout << "Open "<<s_dir<<" director failure."<<endl;
            return -1;
        }
        while(p_Dirent = readdir(p_Dir)){
            if('.'==(p_Dirent->d_name[0])) continue;  
            char str[256];
            memset(str,0,256);
            strcpy(str,s_dir);
            strcat(str,"/");
            strcat(str,p_Dirent->d_name);
            cout <<"found dir: " <<str<<endl;
            count(str);       //嵌套调用
        }
          Dn++;
          return 0;
    }
    else{
        Fn++;
        return 0;
    }
}

15 个解决方案

#1


获取当前目录的子目录数目不需要嵌套的,还是说你的需求描述的不够清楚。

#2


你这个为什么没有处理 ..来,只掠过了当前目录,但是没有略过上层目录,目测是个死循环,并且,你只统计目录,其他的I_IS...来,像是普通文件,CHR,SOCK,PIPE,FIFO,DEV都木有啊有木有,所以应该写的全一点

#3


引用 1 楼 turingo 的回复:
获取当前目录的子目录数目不需要嵌套的,还是说你的需求描述的不够清楚。

这个程序是要实现统计当前目录下所有子目录及所有子目录下文件数与目录数,所以我用了,递归嵌套。

2楼:guochanoo7 目测是死循环不准确.
递归的退出条件是,遇到最下层的空目录,或这遇到最下层是文件。
就是 让while(p_Dirent = readdir(p_Dir))读出是空,退出while,执行{Dn++;return 0;}
或者 if(S_ISDIR(buf.st_mode)),中S_ISDIR(buf.st_mode)为NULL,执行else{ Fn++;return 0;}

#4


输入当前路径的时候,注意最后不要带/符号:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/dir.h>

int isdir(const char* path)
{
struct stat st;
lstat(path, &st);
return S_ISDIR(st.st_mode);
}

int cdf(const char* path, int* dc, int* fc)
{
DIR* dir;
struct dirent* drt;
char filename[256];

if((dir = opendir(path)) == NULL)
return -1;

*dc = *dc + 1;
while((drt = readdir(dir)) != NULL)
{
if(strcmp(drt->d_name, ".") == 0 || strcmp(drt->d_name, "..") == 0)
continue;

sprintf(filename, "%s/%s", path, drt->d_name);
printf("%s\n", filename);
if(isdir(filename))
if(cdf(filename, dc, fc) != 0)
return -1;
else
*fc = *fc + 1;
}

closedir(dir);
return 0;
}

int main(int argc, char* argv[])
{
int dc = 0, fc = 0;

if(argc != 2)
{
printf("Usage: cdf path\n");
return -1;
}

if(cdf(argv[1], &dc, &fc) != 0)
return -1;

printf("dc=%d, fc=%d\n", dc, fc);

return 0;
}

#5


试试递归如何?

#6


这里有个用迭代删除文件夹的例子。可以参考下:
删除文件夹的办法

#7


system("dir /b /a-d c:\\*.* >d:\\allfiles.txt");
//读文件d:\\allfiles.txt的内容即C:\\下所有文件的名字
system("dir /b /ad  c:\\*.* >d:\\alldirs.txt");
//读文件d:\\alldirs.txt的内容即C:\\下所有子目录的名字
请记住,能用shell命令获取文件、文件夹信息或者操作文件、文件夹最好用shell命令获取或者操作,而不要用各种API获取或者操作,因为当遇到非法文件夹名或非法文件名或非法文件长度、非法文件日期、压缩文件、链接文件、稀疏文件……等各种意料之外的情况时,API会处理的不全面或陷入死循环,而shell命令不会。

#8


引用 4 楼 turingo 的回复:
输入当前路径的时候,注意最后不要带/符号:
C/C++ code?12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758#include <stdlib.h>#include <string.h>#include……

统计目录结果正确,统计文件数还有点偏差。
不过已经决定了我的问题。
在此表示感谢,您不愧是大侠。另外思路与编码规范风格都比我强多了。
我明天白天把您那个小问题找到,再过来结贴。
今天晚了,有点困了,不好意思呀

#9


引用 7 楼 zhao4zhong1 的回复:
system("dir /b /a-d c:\\*.* >d:\\allfiles.txt");
//读文件d:\\allfiles.txt的内容即C:\\下所有文件的名字
system("dir /b /ad  c:\\*.* >d:\\alldirs.txt");
//读文件d:\\alldirs.txt的内容即C:\\下所有子目录的名字
请记住,能用shel……

您的结果我还没有试明天试过再给您回复。

#10


引用 4 楼 turingo 的回复:
输入当前路径的时候,注意最后不要带/符号:
C/C++ code?12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758#include <stdlib.h>#include <string.h>#include……

我测试过了,您的程序是正确的。
你的程序里有个小瑕疵,加一对大括号就OK了。
if(isdir(filename)){
            if(cdf(filename, dc, fc) != 0)
                return -1;
       }
        else
            *fc = *fc + 1;
我把您的代码更新如下:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/dir.h>

int isdir(const char* path)
{
struct stat st;
lstat(path, &st);
return S_ISDIR(st.st_mode);
}

int cdf(const char* path, int* dc, int* fc)
{
DIR* dir;
struct dirent* drt;
char filename[256];

if((dir = opendir(path)) == NULL)
return -1;

*dc = *dc + 1;
while((drt = readdir(dir)) != NULL)
{
if(strcmp(drt->d_name, ".") == 0 || strcmp(drt->d_name, "..") == 0)
continue;

sprintf(filename, "%s/%s", path, drt->d_name);
printf("%s\n", filename);
if(isdir(filename)){
if(cdf(filename, dc, fc) != 0)
return -1;
        }
else
*fc = *fc + 1;
}

closedir(dir);
return 0;
}
//检查输入的pathname的末尾是否有‘/’,如果有去掉.但如果输入了2个'/'在路径末尾就没办法了,我这里懒一下没用字符查找函数
int fslash(char* pathname){
    
    int len = strlen(pathname);
    if(len>0){                    
        if(pathname[len-1]=='/'){  
            pathname[len-1]='\0';   
            return 0;
        }
    }else{
        printf("pathname is to less");
        return -1;
    }
}

int main(int argc, char* argv[])
{
int dc = 0, fc = 0;

if(argc != 2)
{
printf("Usage: cdf path\n");
return -1;
}

    fslash(argv[1]);

if(cdf(argv[1], &dc, &fc) != 0)
return -1;

printf("dc=%d, fc=%d\n", dc, fc);

return 0;
}

#11


恩,不错。

引用 10 楼 wchengshen 的回复:
引用 4 楼 turingo 的回复:输入当前路径的时候,注意最后不要带/符号:
C/C++ code?12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758#include <stdlib.h>#include……

#12


引用 7 楼 zhao4zhong1 的回复:
system("dir /b /a-d c:\\*.* >d:\\allfiles.txt");
//读文件d:\\allfiles.txt的内容即C:\\下所有文件的名字
system("dir /b /ad  c:\\*.* >d:\\alldirs.txt");
//读文件d:\\alldirs.txt的内容即C:\\下所有子目录的名字
请记住,能用shel……

您这个方法,我在linux中没找到对应的dir参数表示方法,所以还没测试成功。呵呵,我还很弱
您的思路很对,应该尽量用shell,我想把这个程序用shell再完成一遍。谢谢您

#13


再次对1楼turingo大侠表示感谢。
有网友说我的程序是因为 DIR* p_Dir = NULL;声明成了全局指针变量而不对。
我有点想不通。
为什么不能用一个 DIR*    

#14


ls(list)

功能说明:列出目录内容。

语  法:ls [-1aAbBcCdDfFgGhHiklLmnNopqQrRsStuUvxX][-I <范本样式>][-T <跳格字数>][-w <每列字符数>][--block-size=<区块大小>][--color=<使用时机>][--format=<列表格式>][--full-time][--help][--indicator-style=<标注样式>][--quoting-style=<引号样式>][--show-control-chars][--sort=<排序方式>][--time=<时间戳记>][--version][文件或目录...]

补充说明:执行ls指令可列出目录的内容,包括文件和子目录的名称。

参  数:
  -1   每列仅显示一个文件或目录名称。
  -a或--all   下所有文件和目录。
  -A或--almost-all   显示所有文件和目录,但不显示现行目录和上层目录。
  -b或--escape   显示脱离字符。
  -B或--ignore-backups   忽略备份文件和目录。
  -c   以更改时间排序,显示文件和目录。
  -C   以又上至下,从左到右的直行方式显示文件和目录名称。
  -d或--directory   显示目录名称而非其内容。
  -D或--dired   用Emacs的模式产生文件和目录列表。
  -f   此参数的效果和同时指定"aU"参数相同,并关闭"lst"参数的效果。
  -F或--classify   在执行文件,目录,Socket,符号连接,管道名称后面,各自加上"*","/","=","@","|"号。
  -g   次参数将忽略不予处理。
  -G或--no-group   不显示群组名称。
  -h或--human-readable   用"K","M","G"来显示文件和目录的大小。
  -H或--si   此参数的效果和指定"-h"参数类似,但计算单位是1000Bytes而非1024Bytes。
  -i或--inode   显示文件和目录的inode编号。
  -I<范本样式>或--ignore=<范本样式>   不显示符合范本样式的文件或目录名称。
  -k或--kilobytes   此参数的效果和指定"block-size=1024"参数相同。
  -l   使用详细格式列表。
  -L或--dereference   如遇到性质为符号连接的文件或目录,直接列出该连接所指向的原始文件或目录。
  -m   用","号区隔每个文件和目录的名称。
  -n或--numeric-uid-gid   以用户识别码和群组识别码替代其名称。
  -N或--literal   直接列出文件和目录名称,包括控制字符。
  -o   此参数的效果和指定"-l" 参数类似,但不列出群组名称或识别码。
  -p或--file-type   此参数的效果和指定"-F"参数类似,但不会在执行文件名称后面加上"*"号。
  -q或--hide-control-chars   用"?"号取代控制字符,列出文件和目录名称。
  -Q或--quote-name   把文件和目录名称以""号标示起来。
  -r或--reverse   反向排序。
  -R或--recursive   递归处理,将指定目录下的所有文件及子目录一并处理。
  -s或--size   显示文件和目录的大小,以区块为单位。
  -S   用文件和目录的大小排序。
  -t   用文件和目录的更改时间排序。
  -T<跳格字符>或--tabsize=<跳格字数>   设置跳格字符所对应的空白字符数。
  -u   以最后存取时间排序,显示文件和目录。
  -U   列出文件和目录名称时不予排序。
  -v   文件和目录的名称列表以版本进行排序。
  -w<每列字符数>或--width=<每列字符数>   设置每列的最大字符数。
  -x   以从左到右,由上至下的横列方式显示文件和目录名称。
  -X   以文件和目录的最后一个扩展名排序。
  --block-size=<区块大小>   指定存放文件的区块大小。
  --color=<列表格式>   培植文件和目录的列表格式。
  --full-time   列出完整的日期与时间。
  --help   在线帮助。
  --indicator-style=<标注样式>   在文件和目录等名称后面加上标注,易于辨识该名称所属的类型。
  --quoting-syte=<引号样式>   把文件和目录名称以指定的引号样式标示起来。
  --show-control-chars   在文件和目录列表时,使用控制字符。
  --sort=<排序方式>   配置文件和目录列表的排序方式。
  --time=<时间戳记>   用指定的时间戳记取代更改时间。
  --version   显示版本信息。 

#15


简单的系统调用版本:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc,char* argv[]){
   char path[256];
   sprintf(path,"ls -lR %s|grep ^-|wc -l",argv[1]);
   system(path);
   memset(path,0,256);
   sprintf(path,"ls -lR %s|grep ^d|wc -l",argv[1]);
   system(path);
}

#1


获取当前目录的子目录数目不需要嵌套的,还是说你的需求描述的不够清楚。

#2


你这个为什么没有处理 ..来,只掠过了当前目录,但是没有略过上层目录,目测是个死循环,并且,你只统计目录,其他的I_IS...来,像是普通文件,CHR,SOCK,PIPE,FIFO,DEV都木有啊有木有,所以应该写的全一点

#3


引用 1 楼 turingo 的回复:
获取当前目录的子目录数目不需要嵌套的,还是说你的需求描述的不够清楚。

这个程序是要实现统计当前目录下所有子目录及所有子目录下文件数与目录数,所以我用了,递归嵌套。

2楼:guochanoo7 目测是死循环不准确.
递归的退出条件是,遇到最下层的空目录,或这遇到最下层是文件。
就是 让while(p_Dirent = readdir(p_Dir))读出是空,退出while,执行{Dn++;return 0;}
或者 if(S_ISDIR(buf.st_mode)),中S_ISDIR(buf.st_mode)为NULL,执行else{ Fn++;return 0;}

#4


输入当前路径的时候,注意最后不要带/符号:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/dir.h>

int isdir(const char* path)
{
struct stat st;
lstat(path, &st);
return S_ISDIR(st.st_mode);
}

int cdf(const char* path, int* dc, int* fc)
{
DIR* dir;
struct dirent* drt;
char filename[256];

if((dir = opendir(path)) == NULL)
return -1;

*dc = *dc + 1;
while((drt = readdir(dir)) != NULL)
{
if(strcmp(drt->d_name, ".") == 0 || strcmp(drt->d_name, "..") == 0)
continue;

sprintf(filename, "%s/%s", path, drt->d_name);
printf("%s\n", filename);
if(isdir(filename))
if(cdf(filename, dc, fc) != 0)
return -1;
else
*fc = *fc + 1;
}

closedir(dir);
return 0;
}

int main(int argc, char* argv[])
{
int dc = 0, fc = 0;

if(argc != 2)
{
printf("Usage: cdf path\n");
return -1;
}

if(cdf(argv[1], &dc, &fc) != 0)
return -1;

printf("dc=%d, fc=%d\n", dc, fc);

return 0;
}

#5


试试递归如何?

#6


这里有个用迭代删除文件夹的例子。可以参考下:
删除文件夹的办法

#7


system("dir /b /a-d c:\\*.* >d:\\allfiles.txt");
//读文件d:\\allfiles.txt的内容即C:\\下所有文件的名字
system("dir /b /ad  c:\\*.* >d:\\alldirs.txt");
//读文件d:\\alldirs.txt的内容即C:\\下所有子目录的名字
请记住,能用shell命令获取文件、文件夹信息或者操作文件、文件夹最好用shell命令获取或者操作,而不要用各种API获取或者操作,因为当遇到非法文件夹名或非法文件名或非法文件长度、非法文件日期、压缩文件、链接文件、稀疏文件……等各种意料之外的情况时,API会处理的不全面或陷入死循环,而shell命令不会。

#8


引用 4 楼 turingo 的回复:
输入当前路径的时候,注意最后不要带/符号:
C/C++ code?12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758#include <stdlib.h>#include <string.h>#include……

统计目录结果正确,统计文件数还有点偏差。
不过已经决定了我的问题。
在此表示感谢,您不愧是大侠。另外思路与编码规范风格都比我强多了。
我明天白天把您那个小问题找到,再过来结贴。
今天晚了,有点困了,不好意思呀

#9


引用 7 楼 zhao4zhong1 的回复:
system("dir /b /a-d c:\\*.* >d:\\allfiles.txt");
//读文件d:\\allfiles.txt的内容即C:\\下所有文件的名字
system("dir /b /ad  c:\\*.* >d:\\alldirs.txt");
//读文件d:\\alldirs.txt的内容即C:\\下所有子目录的名字
请记住,能用shel……

您的结果我还没有试明天试过再给您回复。

#10


引用 4 楼 turingo 的回复:
输入当前路径的时候,注意最后不要带/符号:
C/C++ code?12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758#include <stdlib.h>#include <string.h>#include……

我测试过了,您的程序是正确的。
你的程序里有个小瑕疵,加一对大括号就OK了。
if(isdir(filename)){
            if(cdf(filename, dc, fc) != 0)
                return -1;
       }
        else
            *fc = *fc + 1;
我把您的代码更新如下:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/dir.h>

int isdir(const char* path)
{
struct stat st;
lstat(path, &st);
return S_ISDIR(st.st_mode);
}

int cdf(const char* path, int* dc, int* fc)
{
DIR* dir;
struct dirent* drt;
char filename[256];

if((dir = opendir(path)) == NULL)
return -1;

*dc = *dc + 1;
while((drt = readdir(dir)) != NULL)
{
if(strcmp(drt->d_name, ".") == 0 || strcmp(drt->d_name, "..") == 0)
continue;

sprintf(filename, "%s/%s", path, drt->d_name);
printf("%s\n", filename);
if(isdir(filename)){
if(cdf(filename, dc, fc) != 0)
return -1;
        }
else
*fc = *fc + 1;
}

closedir(dir);
return 0;
}
//检查输入的pathname的末尾是否有‘/’,如果有去掉.但如果输入了2个'/'在路径末尾就没办法了,我这里懒一下没用字符查找函数
int fslash(char* pathname){
    
    int len = strlen(pathname);
    if(len>0){                    
        if(pathname[len-1]=='/'){  
            pathname[len-1]='\0';   
            return 0;
        }
    }else{
        printf("pathname is to less");
        return -1;
    }
}

int main(int argc, char* argv[])
{
int dc = 0, fc = 0;

if(argc != 2)
{
printf("Usage: cdf path\n");
return -1;
}

    fslash(argv[1]);

if(cdf(argv[1], &dc, &fc) != 0)
return -1;

printf("dc=%d, fc=%d\n", dc, fc);

return 0;
}

#11


恩,不错。

引用 10 楼 wchengshen 的回复:
引用 4 楼 turingo 的回复:输入当前路径的时候,注意最后不要带/符号:
C/C++ code?12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758#include <stdlib.h>#include……

#12


引用 7 楼 zhao4zhong1 的回复:
system("dir /b /a-d c:\\*.* >d:\\allfiles.txt");
//读文件d:\\allfiles.txt的内容即C:\\下所有文件的名字
system("dir /b /ad  c:\\*.* >d:\\alldirs.txt");
//读文件d:\\alldirs.txt的内容即C:\\下所有子目录的名字
请记住,能用shel……

您这个方法,我在linux中没找到对应的dir参数表示方法,所以还没测试成功。呵呵,我还很弱
您的思路很对,应该尽量用shell,我想把这个程序用shell再完成一遍。谢谢您

#13


再次对1楼turingo大侠表示感谢。
有网友说我的程序是因为 DIR* p_Dir = NULL;声明成了全局指针变量而不对。
我有点想不通。
为什么不能用一个 DIR*    

#14


ls(list)

功能说明:列出目录内容。

语  法:ls [-1aAbBcCdDfFgGhHiklLmnNopqQrRsStuUvxX][-I <范本样式>][-T <跳格字数>][-w <每列字符数>][--block-size=<区块大小>][--color=<使用时机>][--format=<列表格式>][--full-time][--help][--indicator-style=<标注样式>][--quoting-style=<引号样式>][--show-control-chars][--sort=<排序方式>][--time=<时间戳记>][--version][文件或目录...]

补充说明:执行ls指令可列出目录的内容,包括文件和子目录的名称。

参  数:
  -1   每列仅显示一个文件或目录名称。
  -a或--all   下所有文件和目录。
  -A或--almost-all   显示所有文件和目录,但不显示现行目录和上层目录。
  -b或--escape   显示脱离字符。
  -B或--ignore-backups   忽略备份文件和目录。
  -c   以更改时间排序,显示文件和目录。
  -C   以又上至下,从左到右的直行方式显示文件和目录名称。
  -d或--directory   显示目录名称而非其内容。
  -D或--dired   用Emacs的模式产生文件和目录列表。
  -f   此参数的效果和同时指定"aU"参数相同,并关闭"lst"参数的效果。
  -F或--classify   在执行文件,目录,Socket,符号连接,管道名称后面,各自加上"*","/","=","@","|"号。
  -g   次参数将忽略不予处理。
  -G或--no-group   不显示群组名称。
  -h或--human-readable   用"K","M","G"来显示文件和目录的大小。
  -H或--si   此参数的效果和指定"-h"参数类似,但计算单位是1000Bytes而非1024Bytes。
  -i或--inode   显示文件和目录的inode编号。
  -I<范本样式>或--ignore=<范本样式>   不显示符合范本样式的文件或目录名称。
  -k或--kilobytes   此参数的效果和指定"block-size=1024"参数相同。
  -l   使用详细格式列表。
  -L或--dereference   如遇到性质为符号连接的文件或目录,直接列出该连接所指向的原始文件或目录。
  -m   用","号区隔每个文件和目录的名称。
  -n或--numeric-uid-gid   以用户识别码和群组识别码替代其名称。
  -N或--literal   直接列出文件和目录名称,包括控制字符。
  -o   此参数的效果和指定"-l" 参数类似,但不列出群组名称或识别码。
  -p或--file-type   此参数的效果和指定"-F"参数类似,但不会在执行文件名称后面加上"*"号。
  -q或--hide-control-chars   用"?"号取代控制字符,列出文件和目录名称。
  -Q或--quote-name   把文件和目录名称以""号标示起来。
  -r或--reverse   反向排序。
  -R或--recursive   递归处理,将指定目录下的所有文件及子目录一并处理。
  -s或--size   显示文件和目录的大小,以区块为单位。
  -S   用文件和目录的大小排序。
  -t   用文件和目录的更改时间排序。
  -T<跳格字符>或--tabsize=<跳格字数>   设置跳格字符所对应的空白字符数。
  -u   以最后存取时间排序,显示文件和目录。
  -U   列出文件和目录名称时不予排序。
  -v   文件和目录的名称列表以版本进行排序。
  -w<每列字符数>或--width=<每列字符数>   设置每列的最大字符数。
  -x   以从左到右,由上至下的横列方式显示文件和目录名称。
  -X   以文件和目录的最后一个扩展名排序。
  --block-size=<区块大小>   指定存放文件的区块大小。
  --color=<列表格式>   培植文件和目录的列表格式。
  --full-time   列出完整的日期与时间。
  --help   在线帮助。
  --indicator-style=<标注样式>   在文件和目录等名称后面加上标注,易于辨识该名称所属的类型。
  --quoting-syte=<引号样式>   把文件和目录名称以指定的引号样式标示起来。
  --show-control-chars   在文件和目录列表时,使用控制字符。
  --sort=<排序方式>   配置文件和目录列表的排序方式。
  --time=<时间戳记>   用指定的时间戳记取代更改时间。
  --version   显示版本信息。 

#15


简单的系统调用版本:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc,char* argv[]){
   char path[256];
   sprintf(path,"ls -lR %s|grep ^-|wc -l",argv[1]);
   system(path);
   memset(path,0,256);
   sprintf(path,"ls -lR %s|grep ^d|wc -l",argv[1]);
   system(path);
}