0

I want to extract the base name from a string, like

/opt/home/etc/sample

That is, I want to parse a string of large length returning sample, or the substring after the last / character. The string can be of any length.

How could this be done?

4

3 回答 3

6
char *input = "/opt/home/etc/sample";
char *output = NULL;

output = strrchr(input, '/');

if(output != NULL)
{
    printf("%s\n", output);
}

Or otherway is that you can try to parse it all by yourself (Below code is just a sample and doesn't handle all error and boundary conditions, which you can try and learn by yourself)

char *input = "/opt/home/etc/sample";
int len = 0;
char *temp = NULL;

len = strlen(input);
temp = input + (len-1);
len--;

while((*temp != '/') && (len >= 0))
{
  temp--;
  len--;
}


if(len>=0)
{
   printf("%s\n", temp);
}
于 2012-05-16T07:01:07.820 回答
0

You can use strtok_r

#include <stdio.h>
#include <string.h>

int main ()
{
  char str[] ="This/a/sample/string";
  char * pch;
  char * ans;
  printf ("Splitting string \"%s\" into tokens:\n",str);
  pch = strtok_r (str,"/");
  if(pch==NULL)
  ans = str;
  while (pch != NULL)
  {
    ans = pch;
    pch = strtok_r (NULL, "/");
  }
  return 0;
}

P.S please check the code for some small errors

于 2012-05-16T07:02:45.123 回答
0

There are basename / dirname functions in POSIX. Their return value will point to either static memory or some suffix of the input, so there's no need to free it. This may be way easier than to split the string yourself:

  // assuming you own *path:
  char *file = basename(path);
  char *dir = dirname(path);   //that's all!

They also handle the special case when path is "." or ".." or "foo/" (then, basename is "." - the correct thing).

But beware if you don't own the string: They take a non-const argument, and they may modify it.

If you really need to use basename on a const char *, the solution is about the same

  #include <libgen.h>  // POSIX

  void die(const char * errormessage);

  /* version of basename(3) that does not modify its argument.
   * This assumes that "path" is correctly 0-terminated!
   * Please free() the return value after use. */
  char * basename_safe(const char * path)
  {
    char * result;
    char * what_basename_says;

    if (!path) {
      // return a pointer to ".":
      result = malloc(2 * sizeof(char));
      if (!result) die("malloc failed!");
      result[0] = '.';
      result[1] = 0;
      return result;
    }

    // in case path is the empty string, we need 2 chars to store the result ".",
    // so add 2:
    result = malloc((2 + strlen(path)) * sizeof(char));
    if (!result) die("malloc failed");

    // basename wants write access to its argument:
    strcpy(result, path);

    what_basename_says = basename(result);
    // now what_basename_says actually may be a pointer into *result.

    strcpy(result, what_basename_says);
    // to allow for free(result)

    return result;
  }

But, as I said before: if you know that you can modify *path, you may as well use basename without all this.

于 2012-07-02T13:03:15.217 回答