0

私はLinuxでcプログラミングを勉強していて、標準ツール「ls」と「-l」のようなファイルとディレクトリに関する情報を出力するためにこれを書きました。マクロS_ISDIRを除いて、すべて正常に動作します。これが私のコードです。さらに、私のOSはミント14x86_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

システムコール

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にメモリを割り当てさせます。

さらに、マニュアルで推奨されているように、の失敗をテストする必要がstatあります。if(stat(t,&buf) < 0)

もう1つのエラーは、ファイル名を渡さず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

user1198331についての訂正はstat正しかった。エラーを防ぐために、通常、すべてのsyscallの戻り値を確認することをお勧めします。

それでも、元のコードでは、この部分は間違っていたと思います。

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

このリンクからフォローしてみてください。

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