访问 C 中的目录
该程序是打开一个目录并显示文件名...... 即如果有一个文件..它应该说文件....否则目录.. 但程序将所有文件显示为目录..
任何人都可以检查代码是否有任何错误....thnx
#include<stdio.h>
#include<dirent.h>
#define DIR_path "root/test"
main()
{
DIR *dir;
dir=opendir(DIR_PATH);
printf("THe files inside the directory :: \n");
struct dirent *dent;
if(dir!=NULL)
{
while((dent=readdir(dir)))
{
FILE *ptr;
printf(dent->d_name);
if(ptr=fopen(dent->d_name,"r"))
{
print("\tFILE\n");
fclose(ptr);
}
else
printf("\t DIRECTORY\n");
}
close(dir);
}
else
printf("ERROR OPENIN DIRECTORY");
}
The program is to open a directory and to display the name of the files...
i.e if there is a file..it should say FILE....else DIRECTORY..
but the program displays all the files as directory..
Could anyone pls check the code for any errors....thnx
#include<stdio.h>
#include<dirent.h>
#define DIR_path "root/test"
main()
{
DIR *dir;
dir=opendir(DIR_PATH);
printf("THe files inside the directory :: \n");
struct dirent *dent;
if(dir!=NULL)
{
while((dent=readdir(dir)))
{
FILE *ptr;
printf(dent->d_name);
if(ptr=fopen(dent->d_name,"r"))
{
print("\tFILE\n");
fclose(ptr);
}
else
printf("\t DIRECTORY\n");
}
close(dir);
}
else
printf("ERROR OPENIN DIRECTORY");
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
一个问题是目录也是一种文件类型,并且可以正常
fopen()
编辑。您想要对每个文件调用lstat()
来检查它是否是一个目录。像这样:但是这个错误应该导致所有条目都显示为文件。您对该目录下的文件有读取权限吗?
fopen()
调用后errno
的值是多少?One problem is that a directory is also a type of file, and can be normally
fopen()
ed. You want to calllstat()
on each file to check whether it is a directory. Like this:But this error should lead to all entries being displayed as files. Do you have read permissions for the files in this directory? What is the value of
errno
after thefopen()
call?假设
root/test
包含一个名为foo
的文件。对dent=readdir(dir)
的调用将dent->d_name
设置为"foo"
。您已经有了显示以下内容的调试输出:printf(dent->d_name)
¹。然后您尝试使用fopen
打开foo
,但该文件实际上是root/test/foo
。所以每次都会失败(除非当前目录中碰巧还有一个名为 foo 的文件)。有两种方法可以打开正确的文件:
通过将
opendir
的参数与文件名连接来构造文件的完整名称。类似于:<前><代码>/*之前*/
size_t dir_length = strlen(DIR_PATH);
char *文件名 = malloc(dir_length + NAME_MAX + 2); /*错误检查省略*/
strcpy(文件名,DIR_PATH);
文件名[目录长度] = '/';
文件名[目录长度+1] = 0;
while ((dent = readdir(dir)) != NULL) {
strcpy(文件名 + dir_length + 1, dent->d_name);
/*现在对文件名调用 lstat、fopen 等*/
更改为您列出的目录。例如,将 opendir 调用更改为
您必须记住使用
getcwd
和chdir
保存之前的目录。在生产软件中不建议使用此方法,因为由于权限的原因,您可能无法chdir
返回当前目录。slacker已经解释了为什么
fopen
不能用于测试如果文件是目录。¹ 顺便说一下,应该是
puts(dent->d_name)
甚至更好的fputs(dent->d_name, stderr)
:你原来的printf<如果文件名包含
%
, /code> 调用就会中断,这对于调试输出来说不是一个大问题,但却是一个坏习惯。Suppose that
root/test
contains a file calledfoo
. The call todent=readdir(dir)
setsdent->d_name
to"foo"
. You already have debugging output that shows this:printf(dent->d_name)
¹. Then you try to openfoo
withfopen
, but the file is actuallyroot/test/foo
. So this fails every time (unless you happen to also have a file calledfoo
in the current directory).There are two ways to open the right file:
Construct the full name of the file by concatenating the argument to
opendir
with the file name. Something like:Change into the directory you're listing. For example, change the opendir call to
You have to remember to save the previous directory with
getcwd
andchdir
back to it afterwards. This method is not recommended in production software because it is possible to have a current directory that you can'tchdir
back into due to permissions.slacker has already explained why
fopen
can't be used to test if a file is a directory.¹ which by the way should be
puts(dent->d_name)
or even betterfputs(dent->d_name, stderr)
: your originalprintf
call would break if a file name contains%
, which is not a big problem for debugging output but is a bad habit to get into.它是 slacker 和 Gilles 两个答案的组合。使用 lstat 但不要像 slacker 所说的那样使用它。您需要向 lstat 发送完整路径,而不仅仅是 dent->d_name。让您知道 lstat 要求您包含 sys/stat.h>
如果您查看 lstat 的手册页,底部会有一个测试程序,或者只看我的。
这是我的程序,试图模仿 Linux 上的“ls”。注意:转义序列颜色在 Windows 中不起作用,以防您担心可移植性。
its a combination of the two answers by slacker and Gilles. use lstat but don't use it like slacker said. You need to send lstat the full path not just dent->d_name. And just so you know lstat requires you include sys/stat.h>
if you look at the man page for lstat there is a test program at the bottom or just look at mine.
Here is my program that tries to mimick "ls" on linux. Note: escape sequence colors doesn't work in windows just in case you were worried about portability.