Linux 在 C 中实现 ls -al 命令
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13554150/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Implementing the ls -al command in C
提问by ankur3000
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. 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.
作为我的一个班级作业的一部分,我必须用 C 编写一个程序来复制 ls -al 命令的结果。我已经阅读了必要的材料,但我仍然没有得到正确的输出。到目前为止,这是我的代码,它只应该打印出文件大小和文件名,但是它打印的文件大小不正确。
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
安库尔
采纳答案by iabdalkader
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 .
and ..
from the last call to stat()
.
至于为什么它会打印4096
链接的大小.
以及..
从最后一次调用到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;
回答by Jonathan Leffler
The trouble is that when you stat("ankur.txt", &mystat)
, you are not working on the file "Downloads/ankur.txt"
. Most likely, the stat()
is failing; alternatively, it is reporting on a different file.
麻烦的是,当你stat("ankur.txt", &mystat)
在处理文件时,你并不是在处理文件"Downloads/ankur.txt"
。最有可能的stat()
是,失败了;或者,它正在报告不同的文件。
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.
因此,您需要查看您的系统是否支持fstatat()
— POSIX 2008 中的新功能 — 或安排在文件名前加上目录名。
回答by Kristian Glass
I believe you'll observe that if you ./a.out .
you will get the behaviour you expect.
我相信你会观察到,如果./a.out .
你会得到你期望的行为。
You have a slightly subtle bug, observable if you examine the return code of your call to stat(2)
.
您有一个稍微微妙的错误,如果您检查对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
. 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, i.e. that of ..
.
最根本的错误:在dirent
通过返回小号readdir(2)
(在myfile
你的代码)将有一个d_name
相对mydir
。您的代码将stat
..
首先成功,因此mystat
将包含有效数据 for ..
,然后所有后续调用都stat(2)
将失败,返回-1
,您没有检查,因此mystat
不会被修改,您将打印st_size
旧值,即的..
。
回答by user2813853
or maybe just system("ls -al") will also work!
或者也许只是 system("ls -al") 也可以工作!
回答by hbteibet
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);
}