首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

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

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

经典错误,请高人帮忙分析-linux下统计当前目录下的子目录数(当前目录)与其各子目录下的文件数?
有目录结构:
./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;
    }
}


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

#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 
[其他解释]
这里有个用迭代删除文件夹的例子。可以参考下:
删除文件夹的办法
[其他解释]
获取当前目录的子目录数目不需要嵌套的,还是说你的需求描述的不够清楚。
[其他解释]
你这个为什么没有处理 ..来,只掠过了当前目录,但是没有略过上层目录,目测是个死循环,并且,你只统计目录,其他的I_IS...来,像是普通文件,CHR,SOCK,PIPE,FIFO,DEV都木有啊有木有,所以应该写的全一点
[其他解释]
引用:
获取当前目录的子目录数目不需要嵌套的,还是说你的需求描述的不够清楚。

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

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;}
[其他解释]
 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;
}

[其他解释]
试试递归如何?
[其他解释]
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命令不会。

[其他解释]
引用:
输入当前路径的时候,注意最后不要带/符号:


C/C++ code?12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758#include <stdlib.h>#include <string.h>#include……


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

您的结果我还没有试明天试过再给您回复。
[其他解释]
引用:
输入当前路径的时候,注意最后不要带/符号:
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;
}


[其他解释]
恩,不错。

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

[其他解释]
引用:
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再完成一遍。谢谢您
[其他解释]
再次对1楼turingo大侠表示感谢。
有网友说我的程序是因为 DIR* p_Dir = NULL;声明成了全局指针变量而不对。
我有点想不通。
为什么不能用一个 DIR*    

热点排行