如何获得 C 语言的目录列表?

发布于 2024-07-05 03:48:18 字数 40 浏览 4 评论 0原文

如何在 C 语言中扫描目录中的文件夹和文件? 它需要是跨平台的。

How do you scan a directory for folders and files in C? It needs to be cross-platform.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

江湖彼岸 2024-07-12 03:48:18

与 readdir 最相似的方法可能是使用鲜为人知的_find 函数系列

The most similar method to readdir is probably using the little-known _find family of functions.

半窗疏影 2024-07-12 03:48:18

您可以在 wikibooks 链接 上找到示例代码

/**************************************************************
 * A simpler and shorter implementation of ls(1)
 * ls(1) is very similar to the DIR command on DOS and Windows.
 **************************************************************/
#include <stdio.h>
#include <dirent.h>

int listdir(const char *path) 
{
  struct dirent *entry;
  DIR *dp;

  dp = opendir(path);
  if (dp == NULL) 
  {
    perror("opendir");
    return -1;
  }

  while((entry = readdir(dp)))
    puts(entry->d_name);

  closedir(dp);
  return 0;
}

int main(int argc, char **argv) {
  int counter = 1;

  if (argc == 1)
    listdir(".");

  while (++counter <= argc) {
    printf("\nListing %s...\n", argv[counter-1]);
    listdir(argv[counter-1]);
  }

  return 0;
}

You can find the sample code on the wikibooks link

/**************************************************************
 * A simpler and shorter implementation of ls(1)
 * ls(1) is very similar to the DIR command on DOS and Windows.
 **************************************************************/
#include <stdio.h>
#include <dirent.h>

int listdir(const char *path) 
{
  struct dirent *entry;
  DIR *dp;

  dp = opendir(path);
  if (dp == NULL) 
  {
    perror("opendir");
    return -1;
  }

  while((entry = readdir(dp)))
    puts(entry->d_name);

  closedir(dp);
  return 0;
}

int main(int argc, char **argv) {
  int counter = 1;

  if (argc == 1)
    listdir(".");

  while (++counter <= argc) {
    printf("\nListing %s...\n", argv[counter-1]);
    listdir(argv[counter-1]);
  }

  return 0;
}
度的依靠╰つ 2024-07-12 03:48:18

在 C++ 中,我有自己的回调机制来列出文件。 这是代码。

#include <iostream>
#include <functional>
#include <system_error>
#include <sstream>
#include <sys/types.h>
#include <dirent.h>

using namespace std;

auto tmpref( auto &&obj ) { return ref( obj ); };

void listDir( char const *path, function<bool ( dirent & )> const &observer, int *pErr = nullptr );

int main( int argc, char **argv )
{
    listDir( argc > 1 ? argv[1] : ".",
        tmpref( []( dirent &de )
        {
            cout << de.d_name << endl;
            return true;
        } ) );
}
    
void listDir( char const *path, function<bool ( dirent & )> const &observer, int *pErr )
{
    if( pErr )
        *pErr = 0;
    DIR *dir = opendir( path );
    auto err = [&]()
    {
        if( pErr )
            return (void)(*pErr = errno);
        ostringstream oss;
        oss << "enumerating files for directory \"" << path << "\" failed";
        throw system_error( errno, system_category(), oss.str() );
    };
    if( !dir )
        return (void)err();
    errno = 0;
    dirent *de;
    while( (de = readdir( dir )) )
    {
        if( de->d_name == "."sv || de->d_name == ".."sv )
            continue;
        if( !observer( *de ) )
            break;
    }
    if( !de && errno )
        err();
    closedir( dir );
}

正如您从 main() 代码中看到的那样,这节省了很多工作。

In C++ I've got my own callback-mechanismn for listing files. This is the code.

#include <iostream>
#include <functional>
#include <system_error>
#include <sstream>
#include <sys/types.h>
#include <dirent.h>

using namespace std;

auto tmpref( auto &&obj ) { return ref( obj ); };

void listDir( char const *path, function<bool ( dirent & )> const &observer, int *pErr = nullptr );

int main( int argc, char **argv )
{
    listDir( argc > 1 ? argv[1] : ".",
        tmpref( []( dirent &de )
        {
            cout << de.d_name << endl;
            return true;
        } ) );
}
    
void listDir( char const *path, function<bool ( dirent & )> const &observer, int *pErr )
{
    if( pErr )
        *pErr = 0;
    DIR *dir = opendir( path );
    auto err = [&]()
    {
        if( pErr )
            return (void)(*pErr = errno);
        ostringstream oss;
        oss << "enumerating files for directory \"" << path << "\" failed";
        throw system_error( errno, system_category(), oss.str() );
    };
    if( !dir )
        return (void)err();
    errno = 0;
    dirent *de;
    while( (de = readdir( dir )) )
    {
        if( de->d_name == "."sv || de->d_name == ".."sv )
            continue;
        if( !observer( *de ) )
            break;
    }
    if( !de && errno )
        err();
    closedir( dir );
}

As you can see from the main()-code this saves a lot of work.

假情假意假温柔 2024-07-12 03:48:18

我创建了一个开源 (BSD) C 标头来处理这个问题。 目前它支持 POSIX 和 Windows。 请查看:

https://github.com/cxong/tinydir

tinydir_dir dir;
tinydir_open(&dir, "/path/to/dir");

while (dir.has_next)
{
    tinydir_file file;
    tinydir_readfile(&dir, &file);

    printf("%s", file.name);
    if (file.is_dir)
    {
        printf("/");
    }
    printf("\n");

    tinydir_next(&dir);
}

tinydir_close(&dir);

I've created an open source (BSD) C header that deals with this problem. It currently supports POSIX and Windows. Please check it out:

https://github.com/cxong/tinydir

tinydir_dir dir;
tinydir_open(&dir, "/path/to/dir");

while (dir.has_next)
{
    tinydir_file file;
    tinydir_readfile(&dir, &file);

    printf("%s", file.name);
    if (file.is_dir)
    {
        printf("/");
    }
    printf("\n");

    tinydir_next(&dir);
}

tinydir_close(&dir);
我不会写诗 2024-07-12 03:48:18

没有标准的 C(或 C++)方法来枚举目录中的文件。

在 Windows 下,您可以使用 FindFirstFile/FindNextFile 函数枚举目录中的所有条目。 在 Linux/OSX 下使用 opendir/readdir/filledir 函数。

There is no standard C (or C++) way to enumerate files in a directory.

Under Windows you can use the FindFirstFile/FindNextFile functions to enumerate all entries in a directory. Under Linux/OSX use the opendir/readdir/closedir functions.

心凉 2024-07-12 03:48:18

GLib 是一个 C 语言的可移植性/实用程序库,它构成了 GTK+ 图形工具包的基础。 它可以用作独立库。

它包含用于管理目录的便携式包装器。 有关详细信息,请参阅 Glib 文件实用程序 文档。

就我个人而言,如果没有像 GLib 这样的东西支持,我什至不会考虑编写大量的 C 代码。 可移植性是一回事,但免费获得数据结构、线程助手、事件、主循环等也很好。

吉克斯,我几乎开始听起来像个销售人员了:)(别担心,glib 是开源的( LGPL)并且我不以任何方式隶属于它)

GLib is a portability/utility library for C which forms the basis of the GTK+ graphical toolkit. It can be used as a standalone library.

It contains portable wrappers for managing directories. See Glib File Utilities documentation for details.

Personally, I wouldn't even consider writing large amounts of C-code without something like GLib behind me. Portability is one thing, but it's also nice to get data structures, thread helpers, events, mainloops etc. for free

Jikes, I'm almost starting to sound like a sales guy :) (don't worry, glib is open source (LGPL) and I'm not affiliated with it in any way)

天气好吗我好吗 2024-07-12 03:48:18

opendir/readdir 是 POSIX。 如果 POSIX 不足以满足您想要实现的可移植性,请检查 Apache Portable Runtime

opendir/readdir are POSIX. If POSIX is not enough for the portability you want to achieve, check Apache Portable Runtime

太傻旳人生 2024-07-12 03:48:18

目录列表根据所考虑的操作系统/平台的不同而有很大差异。 这是因为,各种操作系统使用自己的内部系统调用来实现这一点。

解决这个问题的方法是寻找一个能够掩盖这个问题并且可移植的库。 不幸的是,没有一种解决方案可以在所有平台上完美运行。

在 POSIX 兼容系统上,您可以使用 Clayton 发布的代码(最初引用自 W. Richard Stevens 的《UNIX 下的高级编程》一书)来使用该库来实现此目的。 该解决方案适用于 *NIX 系统,如果安装了 Cygwin,也适用于 Windows。

或者,您可以编写代码来检测底层操作系统,然后调用适当的目录列表函数,该函数将保留列出该操作系统下目录结构的“正确”方式。

Directory listing varies greatly according to the OS/platform under consideration. This is because, various Operating systems using their own internal system calls to achieve this.

A solution to this problem would be to look for a library which masks this problem and portable. Unfortunately, there is no solution that works on all platforms flawlessly.

On POSIX compatible systems, you could use the library to achieve this using the code posted by Clayton (which is referenced originally from the Advanced Programming under UNIX book by W. Richard Stevens). this solution will work under *NIX systems and would also work on Windows if you have Cygwin installed.

Alternatively, you could write a code to detect the underlying OS and then call the appropriate directory listing function which would hold the 'proper' way of listing the directory structure under that OS.

夏日浅笑〃 2024-07-12 03:48:18

以下 POSIX 程序将打印当前目录中文件的名称:

#define _XOPEN_SOURCE 700
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>

int main (void)
{
  DIR *dp;
  struct dirent *ep;     
  dp = opendir ("./");
  if (dp != NULL)
  {
    while ((ep = readdir (dp)) != NULL)
      puts (ep->d_name);
          
    (void) closedir (dp);
    return 0;
  }
  else
  {
    perror ("Couldn't open the directory");
    return -1;
  }
}

Credit: http://www.gnu.org/software/libtool/manual/libc/Simple-Directory-Lister.html

在 Ubuntu 16.04 中测试。

The following POSIX program will print the names of the files in the current directory:

#define _XOPEN_SOURCE 700
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>

int main (void)
{
  DIR *dp;
  struct dirent *ep;     
  dp = opendir ("./");
  if (dp != NULL)
  {
    while ((ep = readdir (dp)) != NULL)
      puts (ep->d_name);
          
    (void) closedir (dp);
    return 0;
  }
  else
  {
    perror ("Couldn't open the directory");
    return -1;
  }
}

Credit: http://www.gnu.org/software/libtool/manual/libc/Simple-Directory-Lister.html

Tested in Ubuntu 16.04.

貪欢 2024-07-12 03:48:18

严格的答案是“你不能”,因为文件夹的概念本身并不是真正的跨平台。

在 MS 平台上,您可以使用 _findfirst、_findnext 和 _findclose 来实现“c”类型的感觉,并使用 FindFirstFile 和 FindNextFile 来实现底层 Win32 调用。

以下是 C-FAQ 答案:

http://c-faq.com/osdep/readdir.html< /a>

The strict answer is "you can't", as the very concept of a folder is not truly cross-platform.

On MS platforms you can use _findfirst, _findnext and _findclose for a 'c' sort of feel, and FindFirstFile and FindNextFile for the underlying Win32 calls.

Here's the C-FAQ answer:

http://c-faq.com/osdep/readdir.html

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文