Linux "ls -al" 喜欢 C 中的程序

Linux "ls -al" like program in C

我有作业要写一个C程序,它的作用类似于Linux "ls -al"命令。我知道互联网上有很多示例程序,它们正在做我需要的事情,但我有一个特定的问题,我找不到解决方案。我还想提一下,我是 C 编程的新手。这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>
#include <pwd.h> 

int list_dir(const char *dirname)     { 

struct dirent* current_directory;
struct stat my_stat;
struct tm lt;  
struct passwd *pwd; // For User-ID

DIR* directory = opendir(dirname);


    if(directory == NULL)     { 

    printf("list_dir : %s : %s \n", dirname, strerror(errno));

    return 0;
}   

    printf("Directory : %s\n", dirname);
    printf("\n");

    while( (current_directory = readdir(directory) ) )     { 

    stat(current_directory->d_name, &my_stat);  

        if ( (stat(current_directory->d_name, &my_stat) ) == 0 )    {

        pwd = getpwuid(my_stat.st_uid); // Get User-ID

    }

        // Last Modified 
        time_t t = my_stat.st_mtime;
        localtime_r(&t, &lt);
        char timebuf[80];
        strftime(timebuf, sizeof(timebuf), "%c", &lt);

        if (pwd != 0) {

        printf("%s \t %ld \t %s \t %s", pwd->pw_name, (long)my_stat.st_size, timebuf, current_directory->d_name);
        printf("\n");

        } else  {

            printf("%d \t %ld \t %s \t %s", my_stat.st_uid, (long)my_stat.st_size, timebuf, current_directory->d_name);
            printf("\n");
        } 
}
    closedir(directory);        

    return 0; 
}

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

    if ( argc == 1 ) {

    return list_dir ( "." );

    } else {

    int ret = 0;

    for (int i = 1; i < argc; i += 1 ) {

        if ( list_dir ( argv[i] ) != 0 ) {

        ret = 1; 
        }
    }

    return ret;
     } 
} 

该程序必须显示与 "ls -al" 相同的内容(没有权限)。到目前为止一切顺利,如果我用 "gcc -std=gnu99 -o list_dir list_dir.c" 编译它并用“./list_dir” 执行程序,我得到与 "ls -al" 相同的结果,它看起来像这样:

 username    1599    Fri May  1 20:43:57 2015    list_dir.c

但是,如果我 运行 程序带有类似的东西:“./list_dir /home/username/Downloads/” 我得到这个:

 32727   0   Sun May  8 07:09:04 4461391     selection_sort.c

如您所见,程序无法获取有关用户名、文件大小和年份的正确信息。由于 if(pwd != 0) 语句的 else 情况,此信息也出现了。如果我没有 else 情况,程序将只打印出文件,它可以获得正确的信息。另外,如果我删除此 if 语句以及 if 语句:

 if ( (stat(current_directory->d_name, &my_stat) ) == 0 )

我遇到了分段错误。

所以我的问题是: 1.What 我做错了吗?我知道我做错了什么,因为作为家庭作业的提示,我有一个程序示例 运行 以及我可以使用 "stat, lstat, readlink, getpwnam, getpwuid, strftime".

的提示

2.Is 有什么方法可以使用 stat() 和用户 ID 获取用户名,还是只能使用 getpwuid?

这里,

    if ( (stat(current_directory->d_name, &my_stat) ) == 0 ) {
       pwd = getpwuid(my_stat.st_uid); // Get User-ID
    }

如果 stat() 失败会怎样? pwd 将具有未初始化的值或从上一次迭代中设置的不正确的值。

stat 失败的原因是,current_directory->d_name 仅包含文件名,而 stat 需要完整路径。因此,您需要将目录名称添加到文件中并将其传递给 stat()。您现在只传递文件名。

类似于:

   char buf[1024];
   errno = 0;
   snprintf(buf, sizeof buf, "%s/%s", dirname, current_directory->d_name);
   if ( (stat(buf, &my_stat) ) == 0 ) {
     ...
   }
   else {
      printf("%s: %s\n", buf, strerror(errno));
      // exit here or continue to the next entry in the directory 
      //depending how you wish to handle failure
   }

并在 stat() 失败时处理错误。

您在循环中还有另一个 stat(),它什么都不做。