簡體   English   中英

如何在 Linux C 程序中顯示用戶指定名稱為“ls dir_name”的目錄中的所有文件

[英]How to display all files in directory of which name is specified by the user as “ls dir_name” in Linux C program

我正在 C 編程中編寫一個簡單的終端,我想在其中顯示目錄中存在的所有文件,格式為“ls dir_name”。 例如,如果我輸入“ls 下載”之類的命令,它將顯示下載目錄中的所有文件。 我試圖在不同的平台上搜索它,但沒有發現任何有用的信息。 這是我嘗試過的示例代碼,但它僅顯示 pwd 中的那些文件。

#include <dirent.h>
#include <stdio.h>

int main(void)
{
    DIR *d;
    struct dirent *dir;
    d = opendir(".");
    if (d)
    {
        while ((dir = readdir(d)) != NULL)
        {
            printf("%s\n", dir->d_name);
        }
        closedir(d);
    }
    return(0);
}

這是一個可以用作起點的程序。

它需要一個可選的目錄名作為參數,該參數可以相對於當前目錄或完整路徑名。

#include <dirent.h>
#include <stdio.h>

int main(int argc, char **argv)
{
    char *dir_name;
    DIR *d;
    struct dirent *dir;

    if (argc == 0)
      return 1;
    if (argc == 1)
      dir_name = ".";   
    if (argc == 2)
      dir_name = argv[1];
    if (argc > 2)
    {
      printf("usage: myls [directory]\n");
      return 1;
    }

    d = opendir(dir_name);
    if (d)
    {
        while ((dir = readdir(d)) != NULL)
        {
            printf("%s\n", dir->d_name);
        }
        closedir(d);
    }
    else
    {
      printf("directory %s not found\n", dir_name);
      return 1;
    }

    return(0);
}

您使用scandir()

考慮以下示例:

#define _POSIX_C_SOURCE  200809L
#include <stdlib.h>
#include <locale.h>
#include <dirent.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>

int default_filter(const struct dirent *ent)
{
    /* Keep only entries that do not begin with a '.'. */
    return (ent->d_name[0] != '.');
}

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

    /* Use user's locale rules (for alphasort). */
    setlocale(LC_ALL, "");

    /* Usage */
    if (argc < 2 || !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
        const char *this = (argc > 0) ? argv[0] : "(this)";
        fprintf(stderr, "\n");
        fprintf(stderr, "Usage: %s [ -h | --help ]\n", this);
        fprintf(stderr, "       %s DIR [ DIR ... ]\n", this);
        fprintf(stderr, "\n");
        return EXIT_FAILURE;
    }

    for (arg = 1; arg < argc; arg++) {
        struct dirent **list = NULL;
        int             i, count;

        count = scandir(argv[arg], &list, default_filter, alphasort);
        if (count == -1) {
            fprintf(stderr, "%s: %s.\n", argv[arg], strerror(errno));
            return EXIT_FAILURE;
        }

        for (i = 0; i < count; i++) {
            printf("%s\n", list[i]->d_name);
        }
        fflush(stdout);

        free(list);
    }

    return EXIT_SUCCESS;
}

default_filter()是一個目錄條目過濾器,它會跳過(通過返回零)以. ,並保留所有其他人(通過返回非零)。

setlocale(LC_ALL, "")告訴 C 庫使用用戶當前語言環境的規則進行字符類、排序等。

count = scandir(argv[arg], &list, default_filter, alphasort)進行目錄掃描, alphasort()排序的條目(未過濾掉)保存到list ,這是一個動態分配的指向不同結構的指針數組。 (這就是為什么我們需要提供一個指向list的指針:以便 scandir 可以分配一個適當大小的數組。)如果它返回-1 ,則errno發生了一個錯誤,描述了確切的錯誤。 否則, list[i]->d_name包含第i個條目的文件名, i范圍從0count-1 ,包括。

在不再需要這些條目后,一個free(list)將其從 memory 中釋放出來。

這是正確的做法,因為這也是標准實用程序的做法。

上面的示例甚至適用於其他 POSIX-y 操作系統,而不僅僅是 Linux:Mac OS、FreeBSD、OpenBSD 等。

應該使用 opendir()/readdir()/closedir() 的原因是 scandir() (以及nftw()glob() )應該正確處理在列出/掃描文件和目錄時移動的情況/globbed/traversed,但幾乎沒有程序員使用 opendir()/readdir()/closedir() 正確地做到這一點,因為它的工作量太大。

此外,既然已經有了更好的標准版本,為什么還要發明自己的版本呢?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM