function to split a filepath into path and file

前端 未结 6 1515
猫巷女王i
猫巷女王i 2020-12-11 11:10

Lets say I have a function:

void split_path_file(char** p, char** f, char *pf)
{
    //malloc and set *p to file path, malloc and set *f to file name
    //p         


        
相关标签:
6条回答
  • 2020-12-11 11:33

    Maybe a bit late to the party, but the best solution I have found and have been using for years is the two functions dirname and basename

    path         dirname    basename
    "/usr/lib"    "/usr"    "lib"
    "/usr/"       "/"       "usr"
    "usr"         "."       "usr"
    "/"           "/"       "/"
    

    They are great for separating parts of a path/filename. Together with realpath() they are IMHO unbeatable in simplicity and power.

    http://linux.die.net/man/3/basename

    http://man7.org/linux/man-pages/man3/realpath.3.html

    0 讨论(0)
  • 2020-12-11 11:38

    Go backwards through the string until you reach the first '\\' then set *f to everything after it and *p to everything before and the '\\'.

    0 讨论(0)
  • 2020-12-11 11:41

    The simplest way seems to be to start from the end and work towards the beginning, looking for the first delimiter character. You then have two cases: either you found one or you didn't. Something like this should do it for you:

    #include <stdlib.h>
    #include <string.h>
    
    void split_path_file(char **p, char **f, char *pf) {
      char *newcopy = malloc(strlen(pf) + 1);
      strcpy(newcopy, pf);
    
      for (z=newcopy+strlen(newcopy); z>newcopy; z--) {
        if (*z == '/' || *z == '\\')
          break;
      }
    
      if (z > newcopy) {
        *p = newcopy;
        *z = '\0';
        *f = z+1;
      } else {
        *f = newcopy;
        *p = NULL;
      }
    }
    

    Update: @ephemient's comment below points out the above approach doesn't leave *p and *f suitable for calling free(). If this is important, something a little more complicated like this will be needed:

    #include <stdlib.h>
    #include <string.h>
    
    void split_path_file(char **p, char **f, char *pf) {
    
      /* Find last delimiter. */
      char *z;
      for (z=pf+strlen(pf); z>=pf; z--) {
        if (*z == '/' || *z == '\\')
          break;
      }
    
      if (z >= pf) {
        /* There is a delimiter: construct separate
           path and filename fragments. */
        printf("--> %i\n", z-pf);
        *p = malloc(z-pf+1);
        strncpy(*p, pf, z-pf);
        (*p)[z-pf] = '\0';
        *f = malloc(strlen(z));
        strcpy(*f, z+1);
      } else {
        /* There is no delimiter: the entire
           string must be a filename. */
        *p = NULL;
        *f = malloc(strlen(pf)+1);
        strcpy(*f, pf);
      }
    }
    
    0 讨论(0)
  • 2020-12-11 11:46
    int
    stripfilenameandpath (char *path, char *onlypath, char *onlyfilename)
    {
    /*
    documentacao
    
    path = path com path e arquivo
    onlypath = somente o path
    onlyfilename = somente o arquivo sem o path
    
    */
        int ret;
        int i;
        int p;
        char temp[255];
    
        char *fixo;
    #ifdef WIN32
        const int separator = '\\';
    #else
        const int separator = '/';
    #endif
    
        fixo = path;
    
        if (path == NULL)
          {
    
              if (onlypath != NULL)
                {
                    memset (onlypath, 0, 1);
                }
    
              if (onlyfilename != NULL)
                {
                    memset (onlyfilename, 0, 1);
                }
    
              return 1;
          }
    
        ret = strlen (path);
    
        if (!ret)
          {
    
              if (onlypath != NULL)
                {
                    memset (onlypath, 0, 1);
                }
    
              if (onlyfilename != NULL)
                {
                    memset (onlyfilename, 0, 1);
                }
    
              return 0;
          }
    
        for (i = 0; i  -1; i--)
          {
    
              if (temp[i] == separator)
                {
                    temp[i + 1] = 0;
                    break;
                }
              p++;
          }
    
        p = ret - p;
    
        fixo += p + 1;
    
        if (onlypath != NULL)
          {
              strcpy (onlypath, temp);
          }
    
        if (onlyfilename != NULL)
          {
              strcpy (onlyfilename, fixo);
          }
    
        return 0;
    }
    
    
    0 讨论(0)
  • 2020-12-11 11:51

    I came up with the following, of course this assumes that pf is malloced.

    void split_path_file(char** p, char **f, char *pf)
    {
        char *posp = strrchr(pf, '\\');
        *posp = '\0';
        *p = strdup(pf);
        *f = strdup(posp+1);
        *posp = '\\';
    }
    

    Not sure if this is a better approach than above answers.

    0 讨论(0)
  • 2020-12-11 11:57
    void split_path_file(char** p, char** f, char *pf) {
        char *slash = pf, *next;
        while ((next = strpbrk(slash + 1, "\\/"))) slash = next;
        if (pf != slash) slash++;
        *p = strndup(pf, slash - pf);
        *f = strdup(slash);
    }
    

    (If pf == slash, then there is no directory component.)

    0 讨论(0)
提交回复
热议问题