2017-07-04 23 views
1

私はls関数を一からコード化しようとしています。これを行うために、私は各ファイル/構造の情報を含む構造体のリンクリストを作成しました。ここでstat構造体の値に構造体が含まれていません

は構造体である:

typedef struct  s_ls 
{ 
    char   *name; 
    struct   stat stat; 
    struct   s_ls *next; 
}      t_ls; 

私は、リンクされたリストを作成しました:ft_add_elem機能は、新しい構造をmallocをalphabticalために新しい要素を追加し、ポインタを返す

t_ls *ft_store(char *foldername) 
{ 
    t_ls *stock = NULL; 
    DIR *dir; 
    struct dirent *dent; 
    dir = opendir(foldername); 

    if(dir != NULL) 
    { 
     while((dent = readdir(dir)) != NULL) 
     { 
      stock = ft_add_elem(dent->d_name, stock); 
      stat(stock->name, &(stock->stat)); 
     } 
    } 
    return (stock); 
} 

t_ls *ft_new_elem(char *name) 
{ 
    t_ls *tmp; 
    if (!(tmp = malloc(sizeof(t_ls)))) 
     exit(1); 
    tmp->name = ft_strdup(name); 
    return (tmp); 
} 

t_ls *ft_add_elem(char *name, t_ls *stock) 
{ 
    t_ls *new; 
    t_ls *check; 

    new = ft_new_elem(name); 
    if (!stock) 
     return (new); 
    check = stock; 
    while (check && check->next && ft_strcmp(check->next->name, new->name) < 0) 
     check = check->next; 
    new->next = check->next; 
    check->next = new; 
    return (stock); 
} 

私の問題は次のとおりです。 hen私は、最初のものを除いて、すべてのstat構造体が空であるために、-lオプションがトリガされたときにそれらを出力する要素を調べます。しかし、それらをいっぱいにする同じ関数(ft_store)からそれらを出力すると、これは当てはまりません。

+0

こと。それはあなたのコードを読みにくいものにします! – John3136

+2

'在庫 - >次は' unitializedです – ensc

答えて

0

ft_add_elem()は、追加したばかりのアイテムではなく、リストの最初のアイテムへのポインタを返します。並べ替え順にリストを保持しています(ft_strcmp()関数を使用)。したがって、リストの最初の名前にstat()を続けて実行してください。あなたの(現在の)ディレクトリに珍しいファイルがない限り、.になります。

修正するのがもう少し複雑です。 ft_add_elem()stat()の操作を行うのが最善の方法です。ただし、エントリを読み込んでいるディレクトリへのパスについても心配する必要があります。 .(現在のディレクトリ)のみを処理している場合、それは動作します。他のディレクトリを処理している場合は、ファイル名に接頭辞を付けてファイルへのパスを作成する必要があります。

新しい要素が完全に初期化されていることを確認することも重要です。誤って定義されていない動作を回避します。

ここにいくつかの固定コードがあります。 err_で始まる名前の関数は、Github(https://github.com/jleffler/soq/tree/master/src/libsoq)からstderr.cstderr.hにあります。エラー報告を簡素化するために使用されます。

#include "stderr.h" 
#include <dirent.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <sys/stat.h> 
#include <unistd.h> 

#define ft_strcmp(s, t) strcmp(s, t) 
#define ft_strdup(s) strdup(s) 

typedef struct  s_ls 
{ 
    char   *name; 
    struct   stat stat; 
    struct   s_ls *next; 
}      t_ls; 

static t_ls *ft_new_elem(char *name) 
{ 
    t_ls *tmp; 
    if (!(tmp = malloc(sizeof(t_ls)))) 
     err_error("Failed to allocate %zu bytes of memory\n", sizeof(*tmp)); 
    tmp->name = ft_strdup(name); 
    tmp->next = 0; 
    tmp->stat = (struct stat){ 0 }; 
    return(tmp); 
} 

static t_ls *ft_add_elem(char *name, const char *dirname, t_ls *stock) 
{ 
    t_ls *new; 
    t_ls *check; 

    new = ft_new_elem(name); 
    if (!stock) 
     return(new); 
    check = stock; 
    while (check && check->next && ft_strcmp(check->next->name, new->name) < 0) 
     check = check->next; 
    new->next = check->next; 
    check->next = new; 
    char pathname[strlen(dirname) + strlen(name) + 2]; 
    sprintf(pathname, "%s/%s", dirname, name); 
    if (stat(pathname, &new->stat) < 0) 
     err_sysrem("Failed to stat '%s': ", pathname); 
    return(stock); 
} 

static t_ls *ft_store(char *foldername) 
{ 
    t_ls *stock = NULL; 
    DIR *dir; 
    struct dirent *dent; 
    dir = opendir(foldername); 

    if (dir != NULL) 
    { 
     while ((dent = readdir(dir)) != NULL) 
     { 
      stock = ft_add_elem(dent->d_name, foldername, stock); 
     } 
    } 
    return(stock); 
} 

int main(int argc, char **argv) 
{ 
    err_setarg0(argv[0]); 
    if (argc < 2) 
    { 
     argc = 2; 
     argv = (char *[]){ ".", 0 }; 
    } 
    for (int i = 1; i < argc; i++) 
    { 
     t_ls *list = ft_store(argv[i]); 
     t_ls *node = list; 
     while (node != 0) 
     { 
      printf("Name: %s (size %llu)\n", node->name, node->stat.st_size); 
      node = node->next; 
     } 
    } 
    return 0; 
} 

コードでは、C99の機能である2つの複合リテラルが使用されています。同じ効果を達成する他の方法があります。ディレクトリetc上のプログラム(rd37)を実行

は与えた:条約(t_ls)を命名することは恐ろしいです

$ ./rd37 etc 
Name: . (size 0) 
Name: .. (size 2448) 
Name: .gitignore (size 38) 
Name: README.md (size 99) 
Name: posix-opt-end.gif (size 65) 
Name: posix-opt-start.gif (size 69) 
Name: soq-head.mk (size 1618) 
Name: soq-tail.mk (size 665) 
Name: suppressions (size 16139) 
Name: suppressions-macos-10.12.5 (size 4998) 
$ ls -l etc 
total 88 
-rw-r--r-- 1 jleffler staff  99 Jul 9 2016 README.md 
[email protected] 1 jleffler staff  65 Nov 10 2016 posix-opt-end.gif 
[email protected] 1 jleffler staff  69 Nov 10 2016 posix-opt-start.gif 
-rw-r--r-- 1 jleffler staff 1618 Jun 16 23:38 soq-head.mk 
-rw-r--r-- 1 jleffler staff 665 Aug 16 2016 soq-tail.mk 
-rw-r--r-- 1 jleffler staff 16139 Aug 20 2016 suppressions 
-rw-r--r-- 1 jleffler staff 4998 May 21 15:40 suppressions-macos-10.12.5 
$ 
+0

うわー、ありがとうございます!私はそれを見たので、それはかなり明白でした。あなたの時間をありがとう! –

関連する問題