回答編集履歴
4
コード修正
test
CHANGED
@@ -32,7 +32,7 @@
|
|
32
32
|
void freeStack(Stack *stack) {
|
33
33
|
if(stack != NULL) {
|
34
34
|
if(stack->entries != NULL) {
|
35
|
-
for(int i=0; i<stack->top; i++) free(stack->entries[i]);
|
35
|
+
for(int i=0; i<stack->top; i++) freeEntry(stack->entries[i]);
|
36
36
|
free(stack->entries);
|
37
37
|
}
|
38
38
|
free(stack);
|
3
変数名等修正
test
CHANGED
@@ -12,9 +12,6 @@
|
|
12
12
|
#include <string.h>
|
13
13
|
#include <dirent.h>
|
14
14
|
#include <sys/stat.h>
|
15
|
-
|
16
|
-
typedef struct stat Stat;
|
17
|
-
typedef struct dirent DirEnt;
|
18
15
|
|
19
16
|
typedef struct {
|
20
17
|
char path[512];
|
@@ -76,7 +73,7 @@
|
|
76
73
|
}
|
77
74
|
|
78
75
|
int isDirectory(char *path) {
|
79
|
-
|
76
|
+
struct stat st;
|
80
77
|
if(stat(path, &st)) return 0; //false
|
81
78
|
return (st.st_mode & S_IFMT) == S_IFDIR;
|
82
79
|
}
|
@@ -90,25 +87,25 @@
|
|
90
87
|
Stack *stack = allocStack();
|
91
88
|
pushStack(stack, allocEntry(path));
|
92
89
|
|
93
|
-
char work[1024];
|
94
|
-
for(StackEntry *ent
|
90
|
+
for(StackEntry *parent; (parent=popStack(stack)) != NULL; freeEntry(parent)) {
|
95
|
-
printf("ent
|
91
|
+
printf("parent->path=%s\n", parent->path);
|
96
|
-
DIR *dir = opendir(ent
|
92
|
+
DIR *dir = opendir(parent->path);
|
97
93
|
|
98
|
-
for(
|
94
|
+
for(struct dirent *de; (de=readdir(dir)) != NULL; ) {
|
99
95
|
printf("de->d_name=%s\n", de->d_name);
|
100
96
|
if(de->d_name[0] == '.') continue; //"."(カレント),".."(親)および'.'で始まる隠しファイルは無視
|
101
97
|
|
98
|
+
char childpath[1024];
|
102
|
-
sprintf(
|
99
|
+
sprintf(childpath, "%s\\%s", parent->path, de->d_name);
|
103
|
-
if(isDirectory(
|
100
|
+
if(isDirectory(childpath)) {
|
104
|
-
printf("directory: %s\n",
|
101
|
+
printf("directory: %s\n", childpath);
|
105
|
-
pushStack(stack, allocEntry(
|
102
|
+
pushStack(stack, allocEntry(childpath));
|
106
103
|
} else {
|
107
|
-
printf("file: %s\n",
|
104
|
+
printf("file: %s\n", childpath);
|
108
105
|
}
|
109
106
|
}
|
107
|
+
|
110
108
|
closedir(dir);
|
111
|
-
freeEntry(entry);
|
112
109
|
}
|
113
110
|
|
114
111
|
freeStack(stack);
|
@@ -128,7 +125,7 @@
|
|
128
125
|
実行結果
|
129
126
|
```plain
|
130
127
|
> printdir F:\teratail\teratail\aaa
|
131
|
-
ent
|
128
|
+
parent->path=F:\teratail\teratail\aaa
|
132
129
|
de->d_name=.
|
133
130
|
de->d_name=..
|
134
131
|
de->d_name=a1.txt
|
@@ -139,12 +136,12 @@
|
|
139
136
|
directory: F:\teratail\teratail\aaa\bbb
|
140
137
|
de->d_name=zzz
|
141
138
|
directory: F:\teratail\teratail\aaa\zzz
|
142
|
-
ent
|
139
|
+
parent->path=F:\teratail\teratail\aaa\zzz
|
143
140
|
de->d_name=.
|
144
141
|
de->d_name=..
|
145
142
|
de->d_name=z1.txt
|
146
143
|
file: F:\teratail\teratail\aaa\zzz\z1.txt
|
147
|
-
ent
|
144
|
+
parent->path=F:\teratail\teratail\aaa\bbb
|
148
145
|
de->d_name=.
|
149
146
|
de->d_name=..
|
150
147
|
de->d_name=b1.txt
|
2
コード修正
test
CHANGED
@@ -44,12 +44,13 @@
|
|
44
44
|
|
45
45
|
void pushStack(Stack *stack, StackEntry *entry) {
|
46
46
|
if(stack->top == stack->capa || stack->entries == NULL) {
|
47
|
-
stack->capa +
|
47
|
+
int capa = stack->capa + 10;
|
48
|
-
StackEntry **p = realloc(stack->entries, sizeof(StackEntry *) *
|
48
|
+
StackEntry **p = realloc(stack->entries, sizeof(StackEntry *) * capa);
|
49
49
|
if(p == NULL) {
|
50
50
|
printf("pushStack: realloc error.");
|
51
51
|
exit(1);
|
52
52
|
}
|
53
|
+
stack->capa = capa;
|
53
54
|
stack->entries = p;
|
54
55
|
}
|
55
56
|
stack->entries[stack->top++] = entry;
|
@@ -81,6 +82,11 @@
|
|
81
82
|
}
|
82
83
|
|
83
84
|
void printdir(char *path){
|
85
|
+
if(!isDirectory(path)) {
|
86
|
+
printf("file: %s\n", path);
|
87
|
+
return;
|
88
|
+
}
|
89
|
+
|
84
90
|
Stack *stack = allocStack();
|
85
91
|
pushStack(stack, allocEntry(path));
|
86
92
|
|
1
追加
test
CHANGED
@@ -1,2 +1,146 @@
|
|
1
1
|
スタック内に保存するパスは全て違うのですから struct st 毎に領域が必要なのに、全て path になってしまっています。
|
2
2
|
struct st のメンバ p は char ポインタではなく char 配列とし、 path の内容をコピーして保存することになるのでは無いでしょうか。(alloc してもいいですけど。)
|
3
|
+
|
4
|
+
---
|
5
|
+
struct st の要素の使い方よりも、全体的に妙なことになっています。
|
6
|
+
st.l が dirent 配列としても st.i は必要無いはずです。(dopen とか dread がどういうモノなのかはっきりしませんが。)
|
7
|
+
スタックにはパスだけあれば十分だと思います。
|
8
|
+
|
9
|
+
```c
|
10
|
+
#include <stdio.h>
|
11
|
+
#include <stdlib.h>
|
12
|
+
#include <string.h>
|
13
|
+
#include <dirent.h>
|
14
|
+
#include <sys/stat.h>
|
15
|
+
|
16
|
+
typedef struct stat Stat;
|
17
|
+
typedef struct dirent DirEnt;
|
18
|
+
|
19
|
+
typedef struct {
|
20
|
+
char path[512];
|
21
|
+
} StackEntry;
|
22
|
+
|
23
|
+
typedef struct {
|
24
|
+
int top;
|
25
|
+
int capa;
|
26
|
+
StackEntry **entries;
|
27
|
+
} Stack;
|
28
|
+
|
29
|
+
Stack *allocStack() {
|
30
|
+
Stack *stack = malloc(sizeof(Stack));
|
31
|
+
memset(stack, 0, sizeof(Stack));
|
32
|
+
return stack;
|
33
|
+
}
|
34
|
+
|
35
|
+
void freeStack(Stack *stack) {
|
36
|
+
if(stack != NULL) {
|
37
|
+
if(stack->entries != NULL) {
|
38
|
+
for(int i=0; i<stack->top; i++) free(stack->entries[i]);
|
39
|
+
free(stack->entries);
|
40
|
+
}
|
41
|
+
free(stack);
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
45
|
+
void pushStack(Stack *stack, StackEntry *entry) {
|
46
|
+
if(stack->top == stack->capa || stack->entries == NULL) {
|
47
|
+
stack->capa += 10;
|
48
|
+
StackEntry **p = realloc(stack->entries, sizeof(StackEntry *) * stack->capa);
|
49
|
+
if(p == NULL) {
|
50
|
+
printf("pushStack: realloc error.");
|
51
|
+
exit(1);
|
52
|
+
}
|
53
|
+
stack->entries = p;
|
54
|
+
}
|
55
|
+
stack->entries[stack->top++] = entry;
|
56
|
+
}
|
57
|
+
|
58
|
+
StackEntry *popStack(Stack *stack) {
|
59
|
+
if(stack == NULL || stack->top == 0) return NULL;
|
60
|
+
return stack->entries[--stack->top];
|
61
|
+
}
|
62
|
+
|
63
|
+
StackEntry *allocEntry(char *path) {
|
64
|
+
StackEntry *entry = malloc(sizeof(StackEntry));
|
65
|
+
if(entry == NULL) {
|
66
|
+
printf("createEntry: malloc error.");
|
67
|
+
exit(1);
|
68
|
+
}
|
69
|
+
strcpy(entry->path, path);
|
70
|
+
return entry;
|
71
|
+
}
|
72
|
+
|
73
|
+
void freeEntry(StackEntry *entry) {
|
74
|
+
if(entry != NULL) free(entry);
|
75
|
+
}
|
76
|
+
|
77
|
+
int isDirectory(char *path) {
|
78
|
+
Stat st;
|
79
|
+
if(stat(path, &st)) return 0; //false
|
80
|
+
return (st.st_mode & S_IFMT) == S_IFDIR;
|
81
|
+
}
|
82
|
+
|
83
|
+
void printdir(char *path){
|
84
|
+
Stack *stack = allocStack();
|
85
|
+
pushStack(stack, allocEntry(path));
|
86
|
+
|
87
|
+
char work[1024];
|
88
|
+
for(StackEntry *entry; (entry=popStack(stack)) != NULL; ) {
|
89
|
+
printf("entry->path=%s\n", entry->path);
|
90
|
+
DIR *dir = opendir(entry->path);
|
91
|
+
|
92
|
+
for(DirEnt *de; (de=readdir(dir)) != NULL; ) {
|
93
|
+
printf("de->d_name=%s\n", de->d_name);
|
94
|
+
if(de->d_name[0] == '.') continue; //"."(カレント),".."(親)および'.'で始まる隠しファイルは無視
|
95
|
+
|
96
|
+
sprintf(work, "%s\\%s", entry->path, de->d_name);
|
97
|
+
if(isDirectory(work)) {
|
98
|
+
printf("directory: %s\n", work);
|
99
|
+
pushStack(stack, allocEntry(work));
|
100
|
+
} else {
|
101
|
+
printf("file: %s\n", work);
|
102
|
+
}
|
103
|
+
}
|
104
|
+
closedir(dir);
|
105
|
+
freeEntry(entry);
|
106
|
+
}
|
107
|
+
|
108
|
+
freeStack(stack);
|
109
|
+
}
|
110
|
+
|
111
|
+
int main(int argc, char *argv[]) {
|
112
|
+
if(argc != 2) {
|
113
|
+
fprintf(stderr, "Usage: %s <directory-path>\n", argv[0]);
|
114
|
+
exit(1);
|
115
|
+
}
|
116
|
+
printdir(argv[1]);
|
117
|
+
}
|
118
|
+
```
|
119
|
+
フォルダ構成
|
120
|
+

|
121
|
+
|
122
|
+
実行結果
|
123
|
+
```plain
|
124
|
+
> printdir F:\teratail\teratail\aaa
|
125
|
+
entry->path=F:\teratail\teratail\aaa
|
126
|
+
de->d_name=.
|
127
|
+
de->d_name=..
|
128
|
+
de->d_name=a1.txt
|
129
|
+
file: F:\teratail\teratail\aaa\a1.txt
|
130
|
+
de->d_name=a2.txt
|
131
|
+
file: F:\teratail\teratail\aaa\a2.txt
|
132
|
+
de->d_name=bbb
|
133
|
+
directory: F:\teratail\teratail\aaa\bbb
|
134
|
+
de->d_name=zzz
|
135
|
+
directory: F:\teratail\teratail\aaa\zzz
|
136
|
+
entry->path=F:\teratail\teratail\aaa\zzz
|
137
|
+
de->d_name=.
|
138
|
+
de->d_name=..
|
139
|
+
de->d_name=z1.txt
|
140
|
+
file: F:\teratail\teratail\aaa\zzz\z1.txt
|
141
|
+
entry->path=F:\teratail\teratail\aaa\bbb
|
142
|
+
de->d_name=.
|
143
|
+
de->d_name=..
|
144
|
+
de->d_name=b1.txt
|
145
|
+
file: F:\teratail\teratail\aaa\bbb\b1.txt
|
146
|
+
```
|