测试目录为S_ISDIR,但它并不工作

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");
        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);
    
linux
macros
posix
dir
user1198331
user1198331
发布于 2013-02-01
3 个回答
Scylardor
Scylardor
发布于 2018-11-21
已采纳
0 人赞同

用户1198331关于 stat 的修正是正确的。一般来说,检查所有系统调用的返回值是一个好的做法,以防止错误。

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

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

You consider that if S_ISDIR(t->st_mode) returns 0, it is a directory, but actually, S_ISDIR(t->st_mode) returns 0 if the file pointed to by t is not一个目录。因此,你必须做反向检查。

谢谢你的回答,我把我的代码倒过来,这次效果不错。
user1146332
user1146332
发布于 2018-11-21
0 人赞同
int stat(const char *path, struct stat *buf);

不为*buf分配内存。

要么你留在你的声明中

struct stat *buf;

并以手工方式分配内存

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

并在你不需要buf的地方用free释放内存。

或者你把声明改为

struct stat buf;

并让c为你分配内存。

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

另一个错误是,你没有向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");
        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);
    
谢谢你的回答。但问题仍未解决。"logout "是一个目录,但程序的输出是这样的模式。 40755 不是一个目录 链接。 6 组。 1000 用户。 1000 size: 4096 modtime:Fri Feb 1 17:59:53 2013
我附加了一个更正的版本。现在一切正常了。在你的代码中,你没有把文件名传给 stat ,而总是传给目录名...
你是否编译并运行了该程序?它是否给你正确的输出?
是的,我编译了源代码,运行了程序,得到了正确的输出。也许在你的测试案例中, t[256] 并不充分!?
哦,我很困惑。在我的机器上,它仍然给我错误的输出,它不能区分目录和普通文件。
Pabitra Dash
Pabitra Dash
发布于 2018-11-21
0 人赞同

Try following from this link .