0

我正在学习linux中的c编程,我写这个是为了输出文件和目录的信息,比如标准工具“ls”和“-l”,除了宏S_ISDIR,一切都很好,这是我的代码。此外,我的操作系统是 mint 14 x86_64。

#include<sys/types.h>
#include<time.h>
#include<string.h>
#include<dirent.h>
#include<stdio.h>
#include<sys/stat.h>
#include<unistd.h>
void do_ls(char []);
void show_file_info(struct stat *t){
    printf("mode:    %o\n",t->st_mode);
    if(S_ISDIR(t->st_mode)==0)
        printf("Is a dir\n");
    else
        printf("Is not a dir\n");
    printf("links:   %d\n",t->st_nlink);
    printf("group:   %d\n",t->st_gid);
    printf("user:    %d\n",t->st_uid);
    printf("size:    %d\n",t->st_size);
    printf("modtime: %s\n",ctime(&t->st_mtime));
}
int main(int num,char *a[]){
    if(num==1){
        do_ls(".");
    }
    else{
        while(--num){
            printf("%s :\n",*++a);
            do_ls(*a);
        }
    }
}
void do_ls(char dirname[]){
    DIR *tem=opendir(dirname);
    struct dirent *direntp;
    struct stat *buf;
    char t[256];
    if(tem==NULL){
        fprintf(stderr,"ls: cannot open %s\n",dirname);
    }
    else{
        while((direntp=readdir(tem))!=NULL){
            strcpy(t,dirname);
            printf("%s\n",direntp->d_name);
            strcat(t,"/");
            if(stat(t,buf)==-1){
                perror("");
                break;
            }
            else{
                show_file_info(buf);
            }
        }
        closedir(tem);
    }
}
4

3 回答 3

0

关于user1198331的更正stat是正确的。通常检查所有系统调用返回值以防止错误是一个好习惯。

不过,在您的原始代码中,我认为这部分是错误的:

if(S_ISDIR(t->st_mode)==0)
    printf("Is a dir\n");
else
    printf("Is not a dir\n");

您认为如果 S_ISDIR(t->st_mode) 返回 0,则它是一个目录,但实际上,如果 t 指向的文件不是目录,则 S_ISDIR(t->st_mode) 返回 0。因此,您必须进行反向检查。

于 2013-02-01T11:41:52.730 回答
0

系统调用

int stat(const char *path, struct stat *buf);

不为 分配内存*buf

要么你坚持你的声明

struct stat *buf;

并手动分配内存

buf = (struct stat *) malloc(sizeof(struct stat));

free在不再需要的地方释放buf内存

或者您将声明更改为

struct stat buf;

让 c 为你分配内存。

此外,您应该按照手册中的建议测试statwith的失败。if(stat(t,&buf) < 0)

另一个错误是,您没有将文件名传递给stat目录名。

我附加了您的代码的更正版本。


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

void do_ls(char []);

void show_file_info(struct stat *t){
    printf("mode:    %o\n",t->st_mode);
    if((t->st_mode & S_IFMT) == S_IFDIR)
        printf("Is a dir\n");
    else
        printf("Is not a dir\n");
    printf("links:   %d\n",t->st_nlink);
    printf("group:   %d\n",t->st_gid);
    printf("user:    %d\n",t->st_uid);
    printf("size:    %d\n",t->st_size);
    printf("modtime: %s\n",ctime(&t->st_mtime));
}

int main(int num,char *a[]){
    if(num==1){
        do_ls(".");
    }
    else{
        while(--num){
            printf("%s :\n",*++a);
            do_ls(*a);
        }
    }
}

void do_ls(char dirname[]){
    DIR *tem=opendir(dirname);
    struct dirent *direntp;
    struct stat buf;
    char t[256];

    if(tem==NULL){
        fprintf(stderr,"ls: cannot open %s\n",dirname);
    }
    else{
        while((direntp=readdir(tem))!=NULL){
            strcpy(t,dirname);
            printf("%s\n",direntp->d_name);
            strcat(t,"/");
            strcat(t,direntp->d_name);
            if(stat(t,&buf) < 0){
                perror("");
                break;
            }
            else{
                show_file_info(&buf);
            }
        }
        closedir(tem);
    }

}
于 2013-02-01T09:44:18.683 回答
0

尝试从此链接关注。

#ifndef S_ISDIR
#define S_ISDIR(mode)  (((mode) & S_IFMT) == S_IFDIR)
#endif
于 2018-11-21T09:17:52.693 回答