![](/img/trans.png)
[英]Which linux system call is used by ls command in linux to display the folder/file 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
范圍從0
到count-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.