通過readdir()
點返回到靜態分配的結構,所以你不應該做後續調用後保留對它的引用指針,因爲每一次你再打電話readdir()
它只會被覆蓋。
你會想改變:
strArray[count] = (char*)direntp->d_name;
喜歡的東西:
strArray[count] = strdup(direntp->d_name);
做什麼它指向一個副本,而不是隻是想保留指針。當你完成它時,不要忘記撥打free()
,因爲strdup()
malloc()
是你的記憶。
另一種方法是使用readdir_r()
,它使用調用者分配的結構,但由於您只想存儲名稱,因此您可能不需要這樣做。
與往常一樣,沒有從malloc()
在C.把返回
strlen(strArray)
是錯誤的,因爲strArray
不是字符串,並strlen()
僅適用於字符串。您已經保留了一個count
變量來跟蹤它的長度,所以請使用它。這整個塊:
printf("\nTable3: %s \n", strArray[0]);
printf("\nTable3: %s \n", strArray[1]);
printf("\nTable3: %s \n", strArray[2]);
printf("\nTable4: %s \n", strArray[strlen(strArray)-1]);
是一個循環的明顯的候選人,並且可以被替換爲:
for (int s = 0; s < count; ++s) {
printf("\nTable3: %s \n", strArray[s]);
}
或:
int s = 0;
while (strArray[s]) {
printf("\nTable3: %s \n", strArray[s++]);
}
,因爲你的最後一個元素設置爲NULL
。
這裏的一個固定的版本:
#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
char ** do_ls(const char * const dirname) {
DIR * dir_ptr;
struct dirent * direntp;
char ** strArray;
size_t count = 0;
if ((strArray = malloc(sizeof(*strArray))) == NULL) {
fprintf(stderr, "ls1: couldn't allocate memory");
exit(EXIT_FAILURE);
}
strArray[0] = NULL;
if ((dir_ptr = opendir(dirname)) == NULL) {
fprintf(stderr, "ls1: cannot open %s\n", dirname);
exit(EXIT_FAILURE);
}
else {
while ((direntp = readdir(dir_ptr)) != NULL) {
if (strchr(direntp->d_name, '.') == NULL) {
strArray[count] = strdup(direntp->d_name);
if (strArray[count] == NULL) {
fprintf(stderr, "ls1: couldn't allocate memory");
exit(EXIT_FAILURE);
}
printf("Table1: %s\n", strArray[count++]);
printf("Count: %zu\n\n", count);
strArray = realloc(strArray, sizeof(*strArray) * (count + 1));
if (strArray == NULL) {
fprintf(stderr, "ls1: couldn't reallocate memory");
exit(EXIT_FAILURE);
}
strArray[count] = NULL;
}
}
for (size_t s = 0; s < count; ++s) {
printf("Table3: %s\n", strArray[s]);
}
printf("Number of elements: %zu\n\n", count);
closedir(dir_ptr);
}
return strArray;
}
void free_ls_array(char ** strArray) {
size_t s = 0;
while (strArray[s]) {
free(strArray[s++]);
}
free(strArray);
}
int main(void) {
char ** strArray = do_ls("./");
free_ls_array(strArray);
return 0;
}
和輸出:
[email protected]:~/Documents/src/scratch/dir_test$ ls
README ls1 ls1.c nothing.txt
[email protected]:~/Documents/src/scratch/dir_test$ ./ls1
Table1: ls1
Count: 1
Table1: README
Count: 2
Table3: ls1
Table3: README
Number of elements: 2
[email protected]:~/Documents/src/scratch/dir_test$
請充分提供可重現的例子,包括可編譯的代碼和一組顯示問題的文件名。 – merlin2011