C++ 遍历目录下文件简单实现实例

C++ 遍历目录下文件

function:遍历目录下所有文件,返回文件总数,子文件夹总数(修改一下可以获得全部文件名等)。

实例代码:


#include "stdlib.h"
#include "direct.h"
#include "string.h"
#include "io.h"
#include "stdio.h"
#include "iostream"
using namespace std; 

class CBrowseDir
{
protected:
  //存放初始目录的绝对路径,以'\'结尾
  char m_szInitDir[_MAX_PATH]; 

public:
  //缺省构造器
  CBrowseDir(); 

  //设置初始目录为dir,如果返回false,表示目录不可用
  bool SetInitDir(const char *dir); 

  //开始遍历初始目录及其子目录下由filespec指定类型的文件
  //filespec可以使用通配符 * ?,不能包含路径。
  //如果返回false,表示遍历过程被用户中止
  bool BeginBrowse(const char *filespec); 

protected:
  //遍历目录dir下由filespec指定的文件
  //对于子目录,采用迭代的方法
  //如果返回false,表示中止遍历文件
  bool BrowseDir(const char *dir,const char *filespec); 

  //函数BrowseDir每找到一个文件,就调用ProcessFile
  //并把文件名作为参数传递过去
  //如果返回false,表示中止遍历文件
  //用户可以覆写该函数,加入自己的处理代码
  virtual bool ProcessFile(const char *filename); 

  //函数BrowseDir每进入一个目录,就调用ProcessDir
  //并把正在处理的目录名及上一级目录名作为参数传递过去
  //如果正在处理的是初始目录,则parentdir=NULL
  //用户可以覆写该函数,加入自己的处理代码
  //比如用户可以在这里统计子目录的个数
  virtual void ProcessDir(const char *currentdir,const char *parentdir);
}; 

CBrowseDir::CBrowseDir()
{
  //用当前目录初始化m_szInitDir
  getcwd(m_szInitDir,_MAX_PATH); 

  //如果目录的最后一个字母不是'\',则在最后加上一个'\'
  int len=strlen(m_szInitDir);
  if (m_szInitDir[len-1] != '\\')
    strcat(m_szInitDir,"\\");
} 

bool CBrowseDir::SetInitDir(const char *dir)
{
  //先把dir转换为绝对路径
  if (_fullpath(m_szInitDir,dir,_MAX_PATH) == NULL)
    return false; 

  //判断目录是否存在
  if (_chdir(m_szInitDir) != 0)
    return false; 

  //如果目录的最后一个字母不是'\',则在最后加上一个'\'
  int len=strlen(m_szInitDir);
  if (m_szInitDir[len-1] != '\\')
    strcat(m_szInitDir,"\\"); 

  return true;
} 

bool CBrowseDir::BeginBrowse(const char *filespec)
{
  ProcessDir(m_szInitDir,NULL);
  return BrowseDir(m_szInitDir,filespec);
} 

bool CBrowseDir::BrowseDir(const char *dir,const char *filespec)
{
  _chdir(dir); 

  //首先查找dir中符合要求的文件
  long hFile;
  _finddata_t fileinfo;
  if ((hFile=_findfirst(filespec,&fileinfo)) != -1)
  {
    do
    {
      //检查是不是目录
      //如果不是,则进行处理
      if (!(fileinfo.attrib & _A_SUBDIR))
      {
        char filename[_MAX_PATH];
        strcpy(filename,dir);
        strcat(filename,fileinfo.name);
        cout << filename << endl;
        if (!ProcessFile(filename))
          return false;
      }
    } while (_findnext(hFile,&fileinfo) == 0);
    _findclose(hFile);
  }
  //查找dir中的子目录
  //因为在处理dir中的文件时,派生类的ProcessFile有可能改变了
  //当前目录,因此还要重新设置当前目录为dir。
  //执行过_findfirst后,可能系统记录下了相关信息,因此改变目录
  //对_findnext没有影响。
  _chdir(dir);
  if ((hFile=_findfirst("*.*",&fileinfo)) != -1)
  {
    do
    {
      //检查是不是目录
      //如果是,再检查是不是 . 或 ..
      //如果不是,进行迭代
      if ((fileinfo.attrib & _A_SUBDIR))
      {
        if (strcmp(fileinfo.name,".") != 0 && strcmp
          (fileinfo.name,"..") != 0)
        {
          char subdir[_MAX_PATH];
          strcpy(subdir,dir);
          strcat(subdir,fileinfo.name);
          strcat(subdir,"\\");
          ProcessDir(subdir,dir);
          if (!BrowseDir(subdir,filespec))
            return false;
        }
      }
    } while (_findnext(hFile,&fileinfo) == 0);
    _findclose(hFile);
  }
  return true;
} 

bool CBrowseDir::ProcessFile(const char *filename)
{
  return true;
} 

void CBrowseDir::ProcessDir(const char
  *currentdir,const char *parentdir)
{
} 

//从CBrowseDir派生出的子类,用来统计目录中的文件及子目录个数
class CStatDir:public CBrowseDir
{
protected:
  int m_nFileCount;  //保存文件个数
  int m_nSubdirCount; //保存子目录个数 

public:
  //缺省构造器
  CStatDir()
  {
    //初始化数据成员m_nFileCount和m_nSubdirCount
    m_nFileCount=m_nSubdirCount=0;
  } 

  //返回文件个数
  int GetFileCount()
  {
    return m_nFileCount;
  } 

  //返回子目录个数
  int GetSubdirCount()
  {
    //因为进入初始目录时,也会调用函数ProcessDir,
    //所以减1后才是真正的子目录个数。
    return m_nSubdirCount-1;
  } 

protected:
  //覆写虚函数ProcessFile,每调用一次,文件个数加1
  virtual bool ProcessFile(const char *filename)
  {
    m_nFileCount++;
    return CBrowseDir::ProcessFile(filename);
  } 

  //覆写虚函数ProcessDir,每调用一次,子目录个数加1
  virtual void ProcessDir
    (const char *currentdir,const char *parentdir)
  {
    m_nSubdirCount++;
    CBrowseDir::ProcessDir(currentdir,parentdir);
  }
}; 

void main()
{
  //获取目录名
  char buf[256];
  printf("请输入要统计的目录名:");
  gets(buf); 

  //构造类对象
  CStatDir statdir; 

  //设置要遍历的目录
  if (!statdir.SetInitDir(buf))
  {
    puts("目录不存在。");
    return;
  } 

  //开始遍历
  statdir.BeginBrowse("*.*");
  printf("文件总数: %d\n子目录总数:%d\n",statdir.GetFileCount(),statdir.GetSubdirCount());
}

已在windows上验证有效。

下面我加了BeginBrowseFilenames函数,以vector<char*>形式返回目录中所有文件名。

实例代码:

#include "stdlib.h"
#include "direct.h"
#include "string.h"
#include "string"
#include "io.h"
#include "stdio.h"
#include <vector>
#include "iostream"
using namespace std; 

class CBrowseDir
{
protected:
  //存放初始目录的绝对路径,以'\'结尾
  char m_szInitDir[_MAX_PATH]; 

public:
  //缺省构造器
  CBrowseDir(); 

  //设置初始目录为dir,如果返回false,表示目录不可用
  bool SetInitDir(const char *dir); 

  //开始遍历初始目录及其子目录下由filespec指定类型的文件
  //filespec可以使用通配符 * ?,不能包含路径。
  //如果返回false,表示遍历过程被用户中止
  bool BeginBrowse(const char *filespec);
  vector<string> BeginBrowseFilenames(const char *filespec); 

protected:
  //遍历目录dir下由filespec指定的文件
  //对于子目录,采用迭代的方法
  //如果返回false,表示中止遍历文件
  bool BrowseDir(const char *dir,const char *filespec);
  vector<string> GetDirFilenames(const char *dir,const char *filespec);
  //函数BrowseDir每找到一个文件,就调用ProcessFile
  //并把文件名作为参数传递过去
  //如果返回false,表示中止遍历文件
  //用户可以覆写该函数,加入自己的处理代码
  virtual bool ProcessFile(const char *filename); 

  //函数BrowseDir每进入一个目录,就调用ProcessDir
  //并把正在处理的目录名及上一级目录名作为参数传递过去
  //如果正在处理的是初始目录,则parentdir=NULL
  //用户可以覆写该函数,加入自己的处理代码
  //比如用户可以在这里统计子目录的个数
  virtual void ProcessDir(const char *currentdir,const char *parentdir);
}; 

CBrowseDir::CBrowseDir()
{
  //用当前目录初始化m_szInitDir
  getcwd(m_szInitDir,_MAX_PATH); 

  //如果目录的最后一个字母不是'\',则在最后加上一个'\'
  int len=strlen(m_szInitDir);
  if (m_szInitDir[len-1] != '\\')
    strcat(m_szInitDir,"\\");
} 

bool CBrowseDir::SetInitDir(const char *dir)
{
  //先把dir转换为绝对路径
  if (_fullpath(m_szInitDir,dir,_MAX_PATH) == NULL)
    return false; 

  //判断目录是否存在
  if (_chdir(m_szInitDir) != 0)
    return false; 

  //如果目录的最后一个字母不是'\',则在最后加上一个'\'
  int len=strlen(m_szInitDir);
  if (m_szInitDir[len-1] != '\\')
    strcat(m_szInitDir,"\\"); 

  return true;
} 

vector<string> CBrowseDir::BeginBrowseFilenames(const char *filespec)
{
  ProcessDir(m_szInitDir,NULL);
  return GetDirFilenames(m_szInitDir,filespec);
} 

bool CBrowseDir::BeginBrowse(const char *filespec)
{
  ProcessDir(m_szInitDir,NULL);
  return BrowseDir(m_szInitDir,filespec);
} 

bool CBrowseDir::BrowseDir(const char *dir,const char *filespec)
{
  _chdir(dir); 

  //首先查找dir中符合要求的文件
  long hFile;
  _finddata_t fileinfo;
  if ((hFile=_findfirst(filespec,&fileinfo)) != -1)
  {
    do
    {
      //检查是不是目录
      //如果不是,则进行处理
      if (!(fileinfo.attrib & _A_SUBDIR))
      {
        char filename[_MAX_PATH];
        strcpy(filename,dir);
        strcat(filename,fileinfo.name);
        cout << filename << endl;
        if (!ProcessFile(filename))
          return false;
      }
    } while (_findnext(hFile,&fileinfo) == 0);
    _findclose(hFile);
  }
  //查找dir中的子目录
  //因为在处理dir中的文件时,派生类的ProcessFile有可能改变了
  //当前目录,因此还要重新设置当前目录为dir。
  //执行过_findfirst后,可能系统记录下了相关信息,因此改变目录
  //对_findnext没有影响。
  _chdir(dir);
  if ((hFile=_findfirst("*.*",&fileinfo)) != -1)
  {
    do
    {
      //检查是不是目录
      //如果是,再检查是不是 . 或 ..
      //如果不是,进行迭代
      if ((fileinfo.attrib & _A_SUBDIR))
      {
        if (strcmp(fileinfo.name,".") != 0 && strcmp
          (fileinfo.name,"..") != 0)
        {
          char subdir[_MAX_PATH];
          strcpy(subdir,dir);
          strcat(subdir,fileinfo.name);
          strcat(subdir,"\\");
          ProcessDir(subdir,dir);
          if (!BrowseDir(subdir,filespec))
            return false;
        }
      }
    } while (_findnext(hFile,&fileinfo) == 0);
    _findclose(hFile);
  }
  return true;
} 

vector<string> CBrowseDir::GetDirFilenames(const char *dir,const char *filespec)
{
  _chdir(dir);
  vector<string>filename_vector;
  filename_vector.clear(); 

  //首先查找dir中符合要求的文件
  long hFile;
  _finddata_t fileinfo;
  if ((hFile=_findfirst(filespec,&fileinfo)) != -1)
  {
    do
    {
      //检查是不是目录
      //如果不是,则进行处理
      if (!(fileinfo.attrib & _A_SUBDIR))
      {
        char filename[_MAX_PATH];
        strcpy(filename,dir);
        strcat(filename,fileinfo.name);
        filename_vector.push_back(filename);
      }
    } while (_findnext(hFile,&fileinfo) == 0);
    _findclose(hFile);
  }
  //查找dir中的子目录
  //因为在处理dir中的文件时,派生类的ProcessFile有可能改变了
  //当前目录,因此还要重新设置当前目录为dir。
  //执行过_findfirst后,可能系统记录下了相关信息,因此改变目录
  //对_findnext没有影响。
  _chdir(dir);
  if ((hFile=_findfirst("*.*",&fileinfo)) != -1)
  {
    do
    {
      //检查是不是目录
      //如果是,再检查是不是 . 或 ..
      //如果不是,进行迭代
      if ((fileinfo.attrib & _A_SUBDIR))
      {
        if (strcmp(fileinfo.name,".") != 0 && strcmp
          (fileinfo.name,"..") != 0)
        {
          char subdir[_MAX_PATH];
          strcpy(subdir,dir);
          strcat(subdir,fileinfo.name);
          strcat(subdir,"\\");
          ProcessDir(subdir,dir);
          vector<string>tmp= GetDirFilenames(subdir,filespec);
          for (vector<string>::iterator it=tmp.begin();it<tmp.end();it++)
          {
            filename_vector.push_back(*it);
          }
        }
      }
    } while (_findnext(hFile,&fileinfo) == 0);
    _findclose(hFile);
  }
  return filename_vector;
} 

bool CBrowseDir::ProcessFile(const char *filename)
{
  return true;
} 

void CBrowseDir::ProcessDir(const char
  *currentdir,const char *parentdir)
{
} 

//从CBrowseDir派生出的子类,用来统计目录中的文件及子目录个数
class CStatDir:public CBrowseDir
{
protected:
  int m_nFileCount;  //保存文件个数
  int m_nSubdirCount; //保存子目录个数 

public:
  //缺省构造器
  CStatDir()
  {
    //初始化数据成员m_nFileCount和m_nSubdirCount
    m_nFileCount=m_nSubdirCount=0;
  } 

  //返回文件个数
  int GetFileCount()
  {
    return m_nFileCount;
  } 

  //返回子目录个数
  int GetSubdirCount()
  {
    //因为进入初始目录时,也会调用函数ProcessDir,
    //所以减1后才是真正的子目录个数。
    return m_nSubdirCount-1;
  } 

protected:
  //覆写虚函数ProcessFile,每调用一次,文件个数加1
  virtual bool ProcessFile(const char *filename)
  {
    m_nFileCount++;
    return CBrowseDir::ProcessFile(filename);
  } 

  //覆写虚函数ProcessDir,每调用一次,子目录个数加1
  virtual void ProcessDir
    (const char *currentdir,const char *parentdir)
  {
    m_nSubdirCount++;
    CBrowseDir::ProcessDir(currentdir,parentdir);
  }
}; 

void main()
{
  //获取目录名
  char buf[256];
  printf("请输入要统计的目录名:");
  gets(buf); 

  //构造类对象
  CStatDir statdir; 

  //设置要遍历的目录
  if (!statdir.SetInitDir(buf))
  {
    puts("目录不存在。");
    return;
  } 

  //开始遍历 

  vector<string>file_vec = statdir.BeginBrowseFilenames("*.*");
  for(vector<string>::const_iterator it = file_vec.begin(); it < file_vec.end(); ++it)
     std::cout<<*it<<std::endl; 

  printf("文件总数: %d\n",file_vec.size());
  system("pause");
}

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

(0)

相关推荐

  • C++实现图的邻接矩阵存储和广度、深度优先遍历实例分析

    本文实例讲述了C++实现图的邻接矩阵存储和广度.深度优先遍历的方法.分享给大家供大家参考.具体如下: 示例:建立如图所示的无向图 由上图知,该图有5个顶点,分别为a,b,c,d,e,有6条边. 示例输入(按照这个格式输入): 5 6 abcde 0 1 1 0 2 1 0 3 1 2 3 1 2 4 1 1 4 1 输入结束(此行不必输入) 注:0 1 1表示该图的第0个顶点和第1个定点有边相连,如上图中的a->b所示       0 2 1表示该图的第0个顶点和第2个定点有边相连,如上图中的a

  • C++遍历文件夹获取文件列表

    本文实例类似遍历一个文件夹然后获得该文件夹下的文件列表,可以随意切换文件目录,本来是用在我们小组写的简易ftp服务器上的一个给客户端显示的一个小插件,总之单拿出来应该没啥含量,调用了windows的一些API. 实例代码: #include<iostream> #include<stdlib.h> #include<windows.h> #include<fstream> #include<stdio.h> #include<vector&

  • C++实现图的邻接表存储和广度优先遍历实例分析

    本文实例讲述了C++实现图的邻接表存储和广度优先遍历方法.分享给大家供大家参考.具体如下: 示例:建立如图所示的无向图 由上图知,该图有5个顶点,分别为a,b,c,d,e,有6条边. 示例输入(按照这个格式输入): 5 6 abcde 0 1 0 2 0 3 2 3 2 4 1 4 输入结束(此行不必输入) 注:0 1表示该图的第0个顶点和第1个定点有边相连,如上图中的a->b所示       0 2表示该图的第0个顶点和第2个定点有边相连,如上图中的a->c所示       2 3表示该图的

  • c++二叉树的几种遍历算法

    1. 前序/中序/后序遍历(递归实现) 复制代码 代码如下: // 前序遍历void BT_PreOrder(BiTreePtr pNode){ if (!pNode)  return;    visit(pNode);   BT_PreOrder(pNode->left); BT_PreOrder(pNode->right);   }// 中序遍历void BT_PreOrder(BiTreePtr pNode){  if (!pNode)  return;     BT_PreOrder(

  • C++非递归遍历磁盘文件和递归遍历磁盘文件的程序示例

    1:非递归方法: 复制代码 代码如下: // File Name: CSearch.h #pragma once#include <vector>#include <atlstr.h>#include <stack> class Search{private:    std::vector<CString> m_strPath;        // 保存查找到了文件路径    std::vector<CString> m_strSearchNam

  • 一波二叉树遍历问题的C++解答实例分享

    题目一: 输入一颗二元树,从上往下按层打印树的每个节点,同一层按照从左往右的顺序打印. 输入样例: 8 / / 6 10 / / / / 5 7 9 11 输出样例: 复制代码 代码如下: 8 6 10 5 7 9 11 思路分析: 把一颗二叉树抽象成三个节点:根节点.左节点.右节点. 先序遍历即可得到按行输出的效果. 对于左子树只要保存其根节点,既保存了整个左子树.(右子树一样) 对于根节点之外的两个子树来说说,始终是先访问左子树的根节点,再访问右子树的根节点. 因此可以使用队列存储. 代码实

  • 探讨:C++实现链式二叉树(用非递归方式先序,中序,后序遍历二叉树)

    如有不足之处,还望指正! 复制代码 代码如下: // BinaryTree.cpp : 定义控制台应用程序的入口点.//C++实现链式二叉树,采用非递归的方式先序,中序,后序遍历二叉树#include "stdafx.h"#include<iostream>#include<string>#include <stack>using namespace std;template<class T>struct BiNode{ T data; 

  • C++实现二叉树遍历序列的求解方法

    本文详细讲述了C++实现二叉树遍历序列的求解方法,对于数据结构与算法的学习有着很好的参考借鉴价值.具体分析如下: 一.由遍历序列构造二叉树 如上图所示为一个二叉树,可知它的遍历序列分别为: 先序遍历:ABDECFG 中序遍历:DBEAFCG 后序遍历:DEBFGCA 我们需要知道的是,由二叉树的先序序列和中序序列可以唯一地确定一棵二叉树:由二叉树的后序序列和中序序列也可以唯一地确定一棵二叉树:但是如果只知道先序序列和后序序列,则无法唯一确定一棵二叉树. 二.已知二叉树的先序序列和中序序列,求后序

  • C++遍历Lua table的方法实例

    Lua table数据如下: 复制代码 代码如下: --$ cat test.lua lua文件 user = {         ["name"] = "zhangsan",         ["age"] = "22",         ["friend"] = {                 [1] = {                     ["name"] = &quo

  • C++实现哈夫曼树简单创建与遍历的方法

    本文以实例形式讲述了C++实现哈夫曼树简单创建与遍历的方法,比较经典的C++算法. 本例实现的功能为:给定n个带权的节点,如何构造一棵n个带有给定权值的叶节点的二叉树,使其带全路径长度WPL最小. 据此构造出最优树算法如下: 哈夫曼算法: 1. 将n个权值分别为w1,w2,w3,....wn-1,wn的节点按权值递增排序,将每个权值作为一棵二叉树.构成n棵二叉树森林F={T1,T2,T3,T4,...Tn},其中每个二叉树都只有一个权值,其左右字数为空 2. 在森林F中选取根节点权值最小二叉树,

  • C++遍历文件夹下文件的方法

    本文实例讲述了C++遍历文件夹下文件的方法.分享给大家供大家参考.具体如下: #include <windows.h> #include <stdio.h> #include <string.h> #define LEN 1024 // 深度优先递归遍历目录中所有的文件 BOOL DirectoryList(LPCSTR Path) { WIN32_FIND_DATA FindData; HANDLE hError; int FileCount = 0; char Fi

随机推荐