2015-11-05 3 views
0

Je commence en C et j'ai besoin d'utiliser la fonction realpath mais je n'ai pas trouvé beaucoup d'exemples. Je m'en suis servi: link. Mon problème actuel est que ma fonction fonctionne pour un dossier mais que realpath renvoie null lorsqu'il s'agit d'un fichier.Mon chemin retour null pour les fichiers

while ((dir = readdir(rep)) != NULL) 
    { 
     if (!strcmp(dir->d_name, ".") || !strcmp(dir->d_name, "..")) 
      { 
       // do nothing (straight logic) 
     } else { 
      char buf[_POSIX_PATH_MAX]; 
      char *path; 
      path = realpath(dir->d_name, buf); 
      if (!path) 
      { 
        perror("realpath"); 
        exit(EXIT_FAILURE); 
      } 
    } 

EDIT: Le but de ma fonction est d'avoir des realpaths absolue pour les fichiers et dossiers dans le dossier dir

+0

Vous devez vérifier 'errno' après avoir appelé' 'realpath' pour EACCES, EINVAL, EIO, ELOOP, ENAMETOOLONG, ENOENT' ou' ENOTDIR' pour savoir pourquoi . Je soupçonne que vous trouverez qu'il est ENOTDIR. –

+0

Quand je fais: 'printf (" ERREUR:% s \ n ", strerror (errno));' j'ai: 'Aucun fichier ou répertoire'. Je suis sûr que le fichier existe. – filol

+0

Quel est votre répertoire de travail? 'dir-> d_name' est juste le nom de base - le nom du fichier * après * le dernier '/'. –

Répondre

1

Le problème que vous est ne parviennent pas à passer le répertoire courant dans le cadre du nom donné à realpath. Vous ne pouvez pas simplement passer dir->d_name (c'est juste le nom d'un fichier ou d'un sous-répertoire sous le répertoire courant). Vous devez ajouter dir->d_name (avec strcat, etc.) au nom du répertoire que vous avez utilisé dans votre appel à opendir. Exemple:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <dirent.h> 
#include <errno.h> 
#include <unistd.h> 

#ifndef _POSIX_PATH_MAX 
#define _POSIX_PATH_MAX 512 
#endif 

int main (int argc, char **argv) { 

    if (argc < 2) { 
     fprintf (stderr, "error: insufficient arguments. usage: %s dirname\n", 
       argv[0]); 
     return 1; 
    } 

    char *p = argv[1]; 
    size_t len = strlen (p); 
    while (*p && p[len-1] == '/') 
     p[--len] = 0; 

    DIR *rep = opendir (p); 
    struct dirent *dir = NULL; 

    if (!rep) { 
     fprintf (stderr, "error: opendir failed on '%s'\n", p); 
     return 0; 
    } 

    while ((dir = readdir(rep))) 
    { 
     if (!strcmp(dir->d_name, ".") || !strcmp(dir->d_name, "..")) 
     { 
      // do nothing (straight logic) 
     } 
     else { 
      char buf[_POSIX_PATH_MAX] = {0}; 
      char entry[_POSIX_PATH_MAX] = {0}; 
      char *path = NULL; 
      errno = 0; 
      strcat (entry, p); 
      strcat (entry, "/"); 
      strcat (entry, dir->d_name); 
      printf ("getting realpath for : '%s'\n", entry); 
      path = realpath (entry, buf); 
      if (!path || errno) 
      { 
       perror("realpath"); 
       exit(EXIT_FAILURE); 
      } 
      else 
       printf (" realpath for '%s' : %s\n", entry, buf); 
     } 
    } 

    return 0; 
} 

Remarque spécifiquement:

else { 
     char buf[_POSIX_PATH_MAX] = {0}; 
     char entry[_POSIX_PATH_MAX] = {0}; 
     char *path = NULL; 
     errno = 0; 
     strcat (entry, p); 
     strcat (entry, "/"); 
     strcat (entry, dir->d_name); 
     printf ("getting realpath for : '%s'\n", entry); 
     path = realpath (entry, buf); 

entry est la chaîne contenant le répertoire courant, le séparateur '/', et enfin dir->_dname.

Exemple/sortie

$ ./bin/realpathtst debug 
getting realpath for : 'debug/ptrrtn.c' 
realpath for 'debug/ptrrtn.c' : /home/david/dev/src-c/tmp/debug/ptrrtn.c 
getting realpath for : 'debug/structinit.c' 
realpath for 'debug/structinit.c' : /home/david/dev/src-c/tmp/debug/structinit.c 
getting realpath for : 'debug/leetcode.c' 
realpath for 'debug/leetcode.c' : /home/david/dev/src-c/tmp/debug/leetcode.c 
+0

Thx, je travaille sur parce que pour l'instant j'ai core jeté avec mon code. – filol

+0

Thx, ça marche! – filol

+0

Je ne pouvais pas comprendre comment vous avez spécifié le répertoire supérieur du fichier que vous recherchez? Ai-je besoin de savoir où c'est, pour trouver le répertoire exact? Que faire si je souhaite rechercher toutes les commandes de terminal Unix possibles dont je ne connais aucun répertoire supérieur? –