程序是打开一个目录并显示文件的名称...... 即如果有文件..应该说FILE .... else DIRECTORY .. 但程序会将所有文件显示为目录..
任何人都可以检查代码是否有任何错误.... 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");
}
答案 0 :(得分:9)
一个问题是目录也是一种文件,通常可以fopen()
。您想在每个文件上调用lstat()
以检查它是否是目录。像这样:
struct stat st;
lstat(dent->d_name, &st);
if(S_ISDIR(st.st_mode))
printf("\t DIRECTORY\n");
else
printf("\t FILE\n");
但是这个错误应该导致所有条目都显示为文件。您是否对此目录中的文件具有读取权限? errno
致电后fopen()
的价值是多少?
答案 1 :(得分:0)
假设root/test
包含名为foo
的文件。对dent=readdir(dir)
的调用将dent->d_name
设置为"foo"
。您已经有调试输出显示:printf(dent->d_name)
¹。然后,您尝试使用foo
打开fopen
,但该文件实际上是root/test/foo
。所以每次都会失败(除非你碰巧在当前目录中也有一个名为foo
的文件)。
有两种方法可以打开正确的文件:
通过将opendir
的参数与文件名连接来构造文件的全名。类似的东西:
/*before */
size_t dir_length = strlen(DIR_PATH);
char *filename = malloc(dir_length + NAME_MAX + 2); /*error checking omitted*/
strcpy(filename, DIR_PATH);
filename[dir_length] = '/';
filename[dir_length+1] = 0;
while ((dent = readdir(dir)) != NULL) {
strcpy(filename + dir_length + 1, dent->d_name);
/*now call lstat, fopen, etc. on filename*/
转到您要列出的目录。例如,将opendir调用更改为
chdir(DIR_PATH); /*error checking omitted*/
dir = opendir(".");
您必须记住之后将getcwd
和chdir
保存到以前的目录中。在生产软件中不建议使用此方法,因为可能有一个当前目录,由于权限而无法chdir
重新登录。
slacker has already explained why fopen
can't be used to test if a file is a directory.
<子>
¹顺便说一下puts(dent->d_name)
或更好fputs(dent->d_name, stderr)
:如果文件名包含printf
,原始的%
调用会中断,这对于调试来说不是一个大问题输出但是进入的坏习惯。
子>
答案 2 :(得分:0)
这是我试图在linux上模仿“ls”的程序。注意:转义序列颜色在Windows中不起作用,以防您担心可移植性。
#include <iostream>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
int main(int argc,char* argv[]){
char blue[] = { 0x1b, '[', '1', ';', '3', '4', 'm', 0 };
char normal[]={ 0x1b, '[', '0', ';', '3', '9', 'm', 0 };
char green[]= { 0x1b, '[', '0', ';', '3', '2', 'm', 0 };
char red[]= { 0x1b, '[', '0', ';', '3', '1', 'm', 0 };
char cyan[]= { 0x1b, '[', '0', ';', '3', '6', 'm', 0 };
DIR* myDirectory;
char *path=NULL;
size_t size=100;
int result;
char* fullpath;
if (argc >=3){
std::cout<<"Usage: myls <path>"<<std::endl;
return -1;
}
if (argc >= 2){
myDirectory=opendir(argv[1]);
if (errno==ENOENT){
std::cout<<"error: file does not exist"<<std::endl;
return -1;
}
path=argv[1];
if (path[strlen(path)-1]!='/')
strcat(path,"/");
}
else if(argc==1){
path=getcwd(path,size);
strcat(path,"/");
myDirectory=opendir(path);
}
struct stat fileProperties;
struct dirent* directory;
do{
directory=readdir(myDirectory);
if (directory!=NULL){
fullpath=new char[strlen(path)+strlen(directory->d_name)+2];
strcat(fullpath,path);
strcat(fullpath,directory->d_name);
result=lstat(fullpath,&fileProperties);
//std::cout<<result<<fullpath;
switch (fileProperties.st_mode & S_IFMT){
case S_IFDIR: std::cout<<blue;
break;
case S_IFLNK: std::cout<<cyan; break;
case S_IFREG: std::cout<<normal;
default: std::cout<<normal;
if (fileProperties.st_mode & S_IXUSR)
std::cout<<green;
break;
}
std::cout<<directory->d_name<<"\n";
std::cout<<normal;
}
}while(directory!=NULL);
std::cout<<normal<<'\n';
closedir(myDirectory);
delete[] fullpath;
return 0;
}