2012-05-16 18 views
0

我想從一個字符串中提取基礎的名稱,如如何寫的* nix在C基名

/opt/home/etc/sample 

也就是說,我想分析的大長度的字符串返回sample,或後的子字符串 最後的/字符。該字符串可以是任意長度的。

這怎麼辦?

+1

使用'strrpos()'和'substr()'實現。 – alex

+0

@alex,這些是C++函數。 C有'strrchr'。 – ugoren

+0

@ugoren我忘了很多C.你可以隨時在C中實現它們:) – alex

回答

0

您可以使用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; 
} 

PS請檢查代碼中的一些小錯誤

+0

謝謝nischayn22。斯托克給我預期的產出。 – Blackforest

+0

@Blackforest比接受答案;) – nischayn22

+0

-1:如果'str'不包含'/',則不是線程安全的/可重入的+會嚴重失敗。 –

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

output = strrchr(input, '/'); 

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

或者otherway是,你可以嘗試着自己來解析這一切(下面的代碼僅僅是一個樣品,不能處理所有的錯誤和邊界條件,你可以嘗試自己學習)

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); 
} 
0

POSIX中有basename/dirname函數。它們的返回值將指向靜態內存或輸入的後綴,因此不需要釋放它。這可能是比較容易的方式,而不是自己分割字符串:

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

他們也處理特殊情況path".""..""foo/"(當時,基本名稱是"." - 正確的事)。

但要小心如果你不擁有字符串:他們採取非常量參數,他們可能會修改它。

如果你真的需要一個const char *使用basename,該解決方案是差不多的

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

但是,正如我以前說的:如果你知道你可以修改*path,你不妨使用basename沒有這一切。

+0

'strcpy(result,what_basename_says);':正如你所說,'what_basename_says'可能是一個指向'* result'的指針。當's1'和's2'重疊時,'strcpy(s1,s2)'的行爲是** undefined **。 – mk12