提取部分文件路径的简单方法?

时间:2009-01-04 12:10:09

标签: c string

我不擅长C,而且我总是陷入简单的字符串操作任务(这就是我爱Perl的原因!)。

我有一个包含文件路径的字符串,如“/ Volumes / Media / Music / Arcade Fire / Black Mirror.aac”。我需要从该路径中提取驱动器名称(“Media”或最好是“/ Volumes / Media”)。

我会非常感谢任何帮助,就像我试图回复Perl问题一样!

  • 吉姆

5 个答案:

答案 0 :(得分:3)

我认为sscanf可能是合适的:

#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");
}

输出:

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

答案 1 :(得分:1)

我认为你需要在你的问题规范中更准确一点。

当你说要提取“媒体”时,你是指第二个和第三个'/'字符之间的所有内容,还是有更复杂的启发式工作?

此外,缓冲区中的字符串是否适合修改?

通常,执行此操作的方法是使用strchrstrstr一次或多次来查找指向要从中提取子字符串的位置的指针(例如p),和一个指向你需要提取的最后一个字符后面的字符的指针(比如q),如果缓冲区是你不介意破坏的临时缓冲区那么你可以*q = 0和{ {1}}将是指向所需字符串的指针。否则,您需要具有至少p个字符的缓冲区(q - p + 1,以包含空终止符的空间以及+1有趣的字符。例如q - p)和您可以使用char *buffer = malloc(q - p + 1);提取字符串。例如memcpy

答案 2 :(得分:1)

#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");
    }
}

输出:

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

答案 3 :(得分:1)

我认为最简单的方法是使用 strtok()。此函数将在分隔符字符串中的一个字符分隔的标记中拆分字符串。

如果您的原始路径位于 str ,并且您希望第二部分位于部分中:

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

请注意 strtok()会更改 str ,因此它不应该是 const 。如果你有一个 const 字符串,你可以使用 stdrup()来创建副本,这不是标准的,但通常是可用的。

另请注意, strtok()不是线程安全的。

答案 4 :(得分:0)

您的示例使您看起来在Macintosh环境中工作。我怀疑有一个Apple API可以获取特定文件所在的卷。

有什么理由不使用它?

编辑:查看您的个人资料,我怀疑我猜错了您的环境。我帮不了你的窗户。祝好运。我会留下这个以防万一有人在Mac上寻找相同的答案。


从Mac论坛我发现“Getting the current working Volume name?”似乎是同一个问题。那里有一个很好的讨论,但他们似乎没有得到一个答案。

Google是你的朋友。


另一种可能性:CocoaDev论坛上的 BSD Path to Volume Name & Vice-Versa