我不擅长C,而且我总是陷入简单的字符串操作任务(这就是我爱Perl的原因!)。
我有一个包含文件路径的字符串,如“/ Volumes / Media / Music / Arcade Fire / Black Mirror.aac”。我需要从该路径中提取驱动器名称(“Media”或最好是“/ Volumes / Media”)。
我会非常感谢任何帮助,就像我试图回复Perl问题一样!
答案 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)
我认为你需要在你的问题规范中更准确一点。
当你说要提取“媒体”时,你是指第二个和第三个'/'字符之间的所有内容,还是有更复杂的启发式工作?
此外,缓冲区中的字符串是否适合修改?
通常,执行此操作的方法是使用strchr
或strstr
一次或多次来查找指向要从中提取子字符串的位置的指针(例如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。