【问题标题】:count the total number of files present in directory using c++使用 C++ 计算目录中存在的文件总数
【发布时间】:2011-12-24 11:15:19
【问题描述】:

我正在尝试通过 c++ for unix OS
获取目录中的文件数 我有这个代码

int i;
i = (int)system("ls -l /root/opencv/*.png|wc -l");
cout << "Number of files " << i << endl;

但我得到的输出是

21
Number of files 0

如何在i 中获得21

【问题讨论】:

  • 在 bash ls -l /root/opencv/*.png|wc -l 上运行该命令会产生什么结果

标签: c++ filesystems directory


【解决方案1】:

使用 glob(2) 函数可以很容易地实现您想要的:

#include <glob.h>
int glob(const char *pattern, int flags,
                int (*errfunc) (const char *epath, int eerrno),
                glob_t *pglob);

简单示例(无错误处理):

glob_t gl;
size_t num = 0;
if(glob("/root/opencv/*.png", GLOB_NOSORT, NULL, &gl) == 0)
  num = gl.gl_pathc;
globfree(&gl);
cout << "Number of files: " << num << endl;

【讨论】:

  • 很酷的答案。不知道glob 存在。
【解决方案2】:

尽管您指定了一个操作系统,但可能需要一个可移植的解决方案。

Boost::Filesystems directory_iterator 和 std::count_if 是您正在寻找的。 count_if 的谓词可以使用 std::regex 或任何对你来说足够的东西。

这是一个展示所需行为的最小示例(不包括递归):

#include <boost/filesystem.hpp>
#include <iostream>
#include <algorithm>

namespace fs = boost::filesystem;

int main()
{
  int i =  std::count_if(fs::directory_iterator("/your/path/here/"),
                         fs::directory_iterator(), 
                         [](const fs::directory_entry& e) { 
                          return e.path().extension() == ".png";  });
  //also consider recursive_directory_iterator
  std::cout << i << std::endl;
  return 0;
}

【讨论】:

    【解决方案3】:

    system 调用返回 UNIX 中 shell 的退出状态。因此,返回0 是有意义的。

    如果要获取文件数,则需要解析 system 函数的输出。否则,使用系统调用来计算您想要的目录中有多少个 PNG 文件。

    看看opendir 和readdir 函数。最好使用这些函数而不是解析system 输出。

    【讨论】:

    • +1 对不起,我是新手,因为我正在研究 opencv,所以对 c++ 不是很熟悉,但解析你所说的不在这行代码 i = (int)system("ls -l /root/opencv/*.png|wc -l"); 我使用的地方(int)解析。
    • @Wazzzy:你需要解析系统函数调用输出。或者使用execv 之类的东西。我建议您使用opendir 和readdir 来完成您想要完成的任务...
    • @Wazzzy:看看glob的答案。它似乎完全符合您的要求。
    【解决方案4】:

    这是意料之中的。系统的documentation 说:

    返回值

    错误时返回值为 -1(例如 fork(2) 失败),否则返回命令状态。

    您真的不想在此处调用 system 和 ls,执行此操作的标准方法是通过 opendir 和 readdir 进行整个操作,或者通过 glob 如果您只是查找文件名模式。

    如果您坚持生成三个进程来计算目录中的文件数,您应该查看popen 以读取命令的输出。

    【讨论】:

    • 我应该使用i = (int)popen("ls -l /root/opencv/*.png|wc -l","r");
    • 可悲的是,事情并不那么容易(毕竟这是 C 语言......)。 Popen 将返回一个 FILE* 对象,您可以从中读取一个缓冲区,然后您可以从中进行 atoi 或 fscanf ...
    【解决方案5】:

    这是因为你得到的是命令的返回值,而不是输出。

    如果您想使用系统命令ls 而不是其他人建议的opendir 和readdir,则应使用popen 而不是system:

    #include <stdio.h>
    
    int main() 
    {
        FILE *in;
        char buff[512];
    
        /* popen creates a pipe so we can read the output
           of the program we are invoking */
        if (!(in = popen("ls -l /root/opencv/*.png|wc -l", "r"))) 
        {  
            /* if popen failed */
            return 1;
        }
    
        /* read the output of ls, one line at a time */
        while (fgets(buff, sizeof(buff), in) != NULL ) 
        {
            printf("Number of files: %s", buff);
        }
    
        /* close the pipe */
        pclose(in);
        return 0;
    }
    

    【讨论】:

    • 我应该使用i = (int)popen("ls -l /root/opencv/*.png|wc -l","r");
    猜你喜欢
    • 2010-11-10
    • 2012-06-09
    • 2016-09-04
    • 2021-08-25
    • 2014-01-31
    • 2010-10-15
    • 2015-06-27
    • 2011-02-17
    • 1970-01-01
    相关资源
    最近更新 更多