简体   繁体   English

在C中实现ls -al命令

[英]Implementing the ls -al command in C

As a part of an assignment from one of my classes, I have to write a program in C to duplicate the results of the ls -al command. 作为我的一个类的赋值的一部分,我必须在C中编写一个程序来复制ls -al命令的结果。 I have read up on the necessary materials but I am still not getting the right output. 我已经阅读了必要的材料,但我仍然没有得到正确的输出。 Here is my code so far, its only supposed to print out the file size and the file name, but the file sizes its printing are not correct. 这是我的代码到目前为止,它只应打印出文件大小和文件名,但其打印的文件大小不正确。

Code: 码:

#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);
}

These are my results after executing the code: 这些是执行代码后的结果:

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

Here are the correct sizes: 这是正确的尺寸:

[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

Can anyone please point out my mistake. 任何人都可以指出我的错误。

Thanks, 谢谢,

Ankur ANKUR

myfile->d_name is the file name not the path, so you need to append the file name to the directory "Downloads/file.txt" first, if it's is not the working directory: myfile->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);
....

As to why it prints 4096 that is the size of the links . 至于为什么它打印4096这是链接的大小. and .. from the last call to stat() . ..从最后一次调用stat()

Note: you should allocate a buffer large enough to hold the directory name, the file name the NULL byte and the separator, something like this 注意:你应该分配一个足够大的缓冲区来保存目录名,文件名是NULL字节和分隔符,就像这样

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

This is the final code I got to work for anyone interested. 这是我为有兴趣的人工作的最终代码。 It prints the correct file sizes. 它打印正确的文件大小。 Credit goes to asker and mux for answering, just putting the code together. 感谢求问者和多路复用者回答,只是把代码放在一起。 Input I got this to work for is "./main ." 我得到的输入是“./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);
}

I believe you'll observe that if you ./a.out . 我相信你会注意到,如果你./a.out . you will get the behaviour you expect. 你会得到你期望的行为。

You have a slightly subtle bug, observable if you examine the return code of your call to stat(2) . 你有一个稍微微妙的bug,如果你检查你对stat(2)调用的返回码,可以观察到。

The fundamental mistake: the dirent s returned by readdir(2) (the myfile in your code) will have a d_name relative to mydir . 基本错误: readdir(2)返回的dirent readdir(2)代码中的myfile )将具有相对于mydird_name Your code will stat .. first, succeed, and so mystat will contain valid data for .. , then all subsequent calls to stat(2) will fail, returning -1 , which you do not check for, so mystat will not be modified, and you will print the st_size for the old value, ie that of .. . 您的代码将是stat ..首先,成功,因此mystat将包含..有效数据,然后对stat(2)所有后续调用将失败,返回-1 ,您不检查,因此mystat将不会被修改,您将打印旧值的st_size ,即..

The trouble is that when you stat("ankur.txt", &mystat) , you are not working on the file "Downloads/ankur.txt" . 问题是当你使用stat("ankur.txt", &mystat) ,你没有处理文件"Downloads/ankur.txt" Most likely, the stat() is failing; 最有可能的是, stat()失败了; alternatively, it is reporting on a different file. 或者,它报告不同的文件。

Consequently, you need to look at whether your system supports fstatat() — new in POSIX 2008 — or arrange to prefix the name of the file with name of the directory. 因此,您需要查看您的系统是否支持POSIX 2008中的fstatat() - new - 或者安排使用目录名称为文件名添加前缀。

或者只是系统(“ls -al”)也可以工作!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM