Easy way to extract part of a file path?

I'm not very good at C, and I always get stuck on simple string manipulation tasks (that's why I love Perl!).

I have a line that contains a file path like "/ Volumes / Media / Music / Arcade Fire / Black Mirror.aac". I need to extract the drive name ("Media" or "/ Volumes / Media") from this path.

Any help would be greatly appreciated, just as I am trying to return the favor to Perl questions!

  • Jim
+1


source to share


5 answers


I think sscanf might be appropriate:

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

void test(char const* path) {
    int len;
    if(sscanf(path, "/Volumes/%*[^/]%n", &len) != EOF) {
        char *drive = malloc(len + 1);
        strncpy(drive, path, len);
        drive[len] = '\0';

        printf("drive is %s\n", drive);
        free(drive);
    } else {
        printf("match failure\n");
    }
}

int main() {
    test("/Volumes/Media/Foo");
    test("/Volumes/Media");
    test("/Volumes");
}

      



Output:

drive is /Volumes/Media
drive is /Volumes/Media
match failure

      

+3


source


I think you need to be more precise in the specification of your problem.

When you say you want to extract "Media" do you mean everything between the second and third "/" character, or is there a more complex heuristic at work?



Also, is the line in the buffer a valid change?

Usually the way to do this is to use strchr

either strstr

one or more times to find a pointer to where you want to extract the substring from (say p

) and a pointer to the character after the last character you need to extract (say q

) if the buffer is a temporary buffer that you don't mind destruction, then you can just do *q = 0

and p

will be a pointer to the string you want, Otherwise, you need to have a buffer of at least q - p + 1

chars ( +1

must contain a space for the null terminator, as well as interesting q - p

characters, for example char *buffer = malloc(q - p + 1);

) and you can extract the string with memcpy

... for example memcpy(buffer, p, q - p + 1)

.

+1


source


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

char * extractDriveName(const char *path, char separator, int maxLen)
{
    char *outBuffer;
    int outBufferSize, i, j;
    int sepOcur;

    outBufferSize = strlen(path) + 1;
    outBufferSize = outBufferSize > maxLen ? maxLen : outBufferSize;

    outBuffer = (char *) malloc(outBufferSize);

    // Error allocating memory.
    if(outBuffer == NULL)
        return NULL;

    memset(outBuffer, 0, outBufferSize);

    for(i = 0, sepOcur = 0, j = 0; i < outBufferSize; i++)
    {
        if(path[i] == separator)
            sepOcur ++;

        if(sepOcur >= 0 && sepOcur < 3)
            outBuffer[j++] = path[i];
        else if(sepOcur == 3)
            break;      
    }

    // Don't forget to free the buffer if 
    return outBuffer;           
}

int main(void)
{
    char path [] = "/Volumes/Media/Music/Arcade Fire/Black Mirror.aac";

    char * driveName = extractDriveName(path, '/', strlen(path) + 1);

    if(driveName != NULL)
    {
        printf("Path location: '%s'\n", path);
        printf("Drive name: '%s'\n", driveName);
        free(driveName);
    }
    else
    {
        printf("Error allocating memory\n");
    }
}

      

Output:

Path location: '/Volumes/Media/Music/Arcade Fire/Black Mirror.aac'
Drive name: '/Volumes/Media'

      

+1


source


I think the easiest way is to use strtok () . This function splits the string in tokens, separated by one of the delimiter string characters.

If your original path is in str and you want the second part in the part :

strtok(str, "/");        /* To get the first token */
part=strtok(NULL, "/");  /* To get the second token that you want */

      

Note that strtok () will change str , so it shouldn't be const . If you have a const string , you can use stdrup () , which is not standard but usually available, to create a copy.

Also note that strtok () is not thread safe.

+1


source


The example shows that you are using a Macintosh environment. I suspect there is an Apple API to get the volume that a particular file is on.

Any reason not to use this?

Edit: Looking at your profile, I suspect I misunderstood your environment. I cannot help you with windows. Good luck. I'll leave that here in case anyone is looking for the same answer on Mac.


In the Mac forums I find β€œ Getting the current working volume name? ” Which seems to be the same question. There's good discussion out there, but they don't seem to come up with a single answer.

Google is your friend.


Another possibility: BSD Path to Volume Name and Vice Versa on the CocoaDev forums.

0


source







All Articles