2015-12-08 4 views
-1

Я написал программу, которая печатает имя каталога или имя файла. Это легко, но у меня есть что-то неприятное. Невозможно отличить каталог и тип файла. Я знаю, и я использовал stat.st_mode, чтобы закончить его. Но что-то не так: enter image description hereПочему stat не работает после readdir?

Когда я использую gdb для проверки значения st_mode, я обнаружил, что оно равно 0. и "..", поэтому вот вопрос: почему st_mode равно 0?

и что мой код:

#include <stdio.h> 
#include <stdlib.h> 
#include <dirent.h> 
#include <sys/stat.h> 

int main(void) 
{ 
DIR *pDir = opendir("MyDirectory"); 
struct dirent *pDirent; 
struct stat vStat; 

if (pDir == NULL) 
{ 
    printf("Can't open the directory \"MyDirectory\""); 
    exit(1); 
} 

while ((pDirent = readdir(pDir)) != NULL) 
{ 
    stat(pDirent->d_name, &vStat); 
    if (S_ISDIR(vStat.st_mode)) 
     printf("Directory: %s\n", pDirent->d_name); 
    else 
     printf("File: %s\n", pDirent->d_name); 
} 

closedir(pDir); 
return 0; 
} 
+3

Неужели 'stat' терпит неудачу? – immibis

+0

извините, errno == 2 означает Нет такого файла или каталога –

+1

Не публикуйте скриншоты. Вы должны опубликовать текст, если у вас нет проблемы с самим скриншотом. – Olaf

ответ

5

Классический readdir ошибка: pDirent->d_name это имя записи каталога, а не путь к файлу. Это "1", "4-5.c" и т. Д. Итак, ваши stat звонки ищут файл с таким именем в текущем каталоге, а не под MyDirectory.

Проверьте возвращаемое значение stat. Вы увидите, что это ENOENT - за исключением . и .., которые также существуют в текущем каталоге. Когда stat сбой, содержимое структуры stat не определено.

Если вы звоните opendir в каталог, отличный от ., то для выполнения всего полезного с возвращенными именами вам нужно построить полный путь. Скопируйте путь, который вы передали в opendir, в буфер с достаточным пространством для косой черты и имени файла и скопируйте каждое имя файла в этот буфер. Код ошибки подтверждения (ошибка проверки опущена и т. Д.):

char *directory = "MyDirectory"; 
size_t directory_length = strlen(directory); 
char *path = malloc(directory_length + 1 + NAME_MAX); 
strcpy(path, directory); 
path[directory_length] = '/'; 
while ((pDirent = readdir(pDir)) != NULL) { 
    strcpy(path + directory_length + 1, pDirent->d_name); 
    if (stat(path, &vStat) == -1) { 
     perror(path); 
     continue; 
    } 
    … 
} 
+0

Благодарим вас за ответ! Теперь я знаю причину. Да, ты прав, и это лучший способ, я думаю. И я также получил другой способ: это использование chdir (pathname), и это тоже сработало. –