¿Por qué la estadística no funciona después de readdir?

Escribí un progtwig que imprime el nombre del directorio o el nombre del archivo. Es fácil, pero tengo algo de problemas. No pudo distinguir el directorio y el tipo de archivo. Lo sé y utilicé stat.st_mode para terminarlo. Pero algo está mal: enter image description here

cuando uso gdb para verificar el valor de st_mode, encontré que era 0, excepto “.” y “..”, así que aquí está la pregunta: ¿por qué st_mode es 0?

y ese es mi código:

#include  #include  #include  #include  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; } 

Error readdir clásico: pDirent->d_name es el nombre de la entrada del directorio, no una ruta al archivo. Es "1" , "4-5.c" , etc. Por lo tanto, sus llamadas stat están buscando un archivo con ese nombre en el directorio actual , no en MyDirectory .

Verifique el valor de retorno de stat . Verás que está ENOENT – excepto por . y .. , que también existen en el directorio actual. Cuando la stat falla, el contenido de la estructura estadística no está definido.

Si llama a opendir en un directorio que no sea . , entonces para hacer prácticamente cualquier cosa útil con los nombres devueltos, debe comstackr una ruta completa. Copie la ruta que pasó a opendir en un búfer con suficiente espacio para una barra diagonal y un nombre de archivo además, y copie cada nombre de archivo en ese búfer. Código de prueba de concepto (se omite la comprobación de errores, etc.):

 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; } … }