【问题标题】:Implementing the ls -al command in C在 C 中实现 ls -al 命令
【发布时间】:2012-11-13 07:09:33
【问题描述】:

作为我的一个课程的作业的一部分,我必须用 C 编写一个程序来复制 ls -al 命令的结果。我已经阅读了必要的材料,但仍然没有得到正确的输出。到目前为止,这是我的代码,它只应该打印出文件大小和文件名,但其打印的文件大小不正确。

代码:

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>

int main(int argc, char* argv[])
{
    DIR *mydir;
    struct dirent *myfile;
    struct stat mystat;

    mydir = opendir(argv[1]);
    while((myfile = readdir(mydir)) != NULL)
    {
        stat(myfile->d_name, &mystat);    
        printf("%d",mystat.st_size);
        printf(" %s\n", myfile->d_name);
    }
    closedir(mydir);
}

这些是我执行代码后的结果:

[root@localhost ~]# ./a.out Downloads
4096 ..
4096 hw22.c
4096 ankur.txt
4096 .
4096 destination.txt

以下是正确的尺寸:

[root@localhost ~]# ls -al Downloads
total 20
drwxr-xr-x.  2 root root 4096 Nov 26 01:35 .
dr-xr-x---. 24 root root 4096 Nov 26 01:29 ..
-rw-r--r--.  1 root root   27 Nov 21 06:32 ankur.txt
-rw-r--r--.  1 root root   38 Nov 21 06:50 destination.txt
-rw-r--r--.  1 root root 1139 Nov 25 23:38 hw22.c

谁能指出我的错误。

谢谢,

安库尔

【问题讨论】:

  • 对我来说没问题。检查stat()的返回值是否有错误。
  • 在这里也可以正常工作。为所有内容引入错误检查(opendir()、readdir()、stat())。
  • 如果你在 . 上运行它可以正常工作,但如果你给它另一个目录就不行。
  • 这不是问题的重点,但我建议您不要以 root 身份运行程序(尤其是在学习时)。我会改为使用 sudo 以 root 身份运行特定程序

标签: c linux file ls stat


【解决方案1】:

myfile-&gt;d_name是文件名而不是路径,所以如果不是工作目录,则需要先将文件名附加到目录"Downloads/file.txt"

char buf[512];    
while((myfile = readdir(mydir)) != NULL)
{
    sprintf(buf, "%s/%s", argv[1], myfile->d_name);
    stat(buf, &mystat);
....

至于为什么它会打印4096,即上次调用stat()时链接...的大小。

注意:你应该分配一个足够大的缓冲区来保存目录名、文件名NULL字节和分隔符,像这样

strlen(argv[1]) + NAME_MAX + 2;

【讨论】:

  • 非常感谢您的回复,使您的建议添加工作。该程序现在提供正确的文件大小。谢谢。
  • 这在我的操作系统论文中非常有用,我需要在内核 2.6.39 中安装驱动程序,使用 qemu 和一个 init 进行模拟。我仍然没有弄清楚,但谢谢! !哈哈!!
【解决方案2】:

这是我为任何感兴趣的人工作的最终代码。它打印正确的文件大小。归功于 asker 和 mux 的回答,只需将代码放在一起。我得到这个工作的输入是“./main”。 .

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>

int main(int argc, char* argv[])
{
    DIR *mydir;
    struct dirent *myfile;
    struct stat mystat;

    char buf[512];
    mydir = opendir(argv[1]);
    while((myfile = readdir(mydir)) != NULL)
    {
        sprintf(buf, "%s/%s", argv[1], myfile->d_name);
        stat(buf, &mystat);
        printf("%zu",mystat.st_size);
        printf(" %s\n", myfile->d_name);
    }
    closedir(mydir);
}

【讨论】:

    【解决方案3】:

    我相信你会发现,如果你./a.out .,你会得到你期望的行为。

    如果您检查对stat(2) 的调用的返回码,您会发现一个稍微微妙的错误。

    基本错误:readdir(2)(代码中的myfile)返回的dirents 相对于mydir 将具有d_name。您的代码将首先stat .. 成功,因此mystat 将包含.. 的有效数据,然后对stat(2) 的所有后续调用将失败,返回-1,您不检查,所以mystat不会被修改,你将打印st_size作为旧值,即..的值。

    【讨论】:

    • 感谢您的回复,我现在在我的代码中看到了问题。但究竟为什么会发生这种情况?我以为当我们执行 opendir() 命令时,程序会自动调整该目录的文件路径。
    【解决方案4】:

    问题是当你stat("ankur.txt", &amp;mystat) 时,你不是在处理文件"Downloads/ankur.txt"。最有可能的是,stat() 失败了;或者,它正在报告不同的文件。

    因此,您需要查看您的系统是否支持fstatat() — POSIX 2008 中的新功能 — 或者安排在文件名前加上目录名。

    【讨论】:

      【解决方案5】:

      或者只是 system("ls -al") 也可以!

      【讨论】:

      • 它根本没有回答问题。
      猜你喜欢
      • 2016-07-25
      • 2017-04-09
      • 2022-11-13
      • 2012-06-09
      • 2014-05-30
      • 2015-07-11
      • 1970-01-01
      • 2013-03-13
      • 1970-01-01
      相关资源
      最近更新 更多