用“/”提取字符串

时间:2014-09-15 14:36:00

标签: c

我可以使用strtok提取字符串fs和lost + found,并将分隔符设置为“/”。但我无法将标记化的字符串连接到/ fs / lost + found /

#include<stdio.h>
#include<string.h>
char* path_val(char* paths){
        char* temp =  strtok(paths,"/");
        char* path = temp;
        char* begin = path;
        printf("\n %s \n",temp);
        /* Concatenating with /fs */
        strcat(path,"/");
        strcat(path,temp);
        while(temp != NULL){
                if(strcmp(temp,"lost+found") == 0){
                         printf("\n Found! \n");
                         /* Concatenating with / and lost+found */
                         strcat(path,"/");
                         strcat(path,temp);
                         printf("\n path : %s \n",begin);
                         return temp;
                }
                temp = strtok(NULL,"/");
        }
}
int main(){
        char path[] = "/fs/lost+found/df/er/te";
        char *name = path_val(path);
        printf("\n name : %s \n",name);
        return 0;
}

我想提取/ fs / lost + found。试过上面的程序,但无法得到正确的字符串。

2 个答案:

答案 0 :(得分:2)

您的代码中存在多个问题:

  • 您将缓冲区多次传递给strtok以获取不同的令牌,同时使用strcat对其进行修改。那很糟。更糟糕的是,你所要做的缓冲区path已经是同一个缓冲区的一部分了。正如哈珀所说,它会导致未定义的行为
  • 您没有返回正确的值:您只返回最后一个令牌而不是返回整个前缀

您可以尝试以下方式:

#include<stdio.h>
#include<string.h>
char* path_val(char* paths){
        char* path = (char *) malloc(1 + strlen(paths));
        char* temp =  strtok(paths,"/");
        char* begin = path;
        printf("\n %s \n",temp);
        while(temp != NULL){
                strcat(path,"/");
                strcat(path,temp);
                if(strcmp(temp,"lost+found") == 0){
                         printf("\n Found! \n");
                         printf("\n path : %s \n",begin);
                         return path;
                }
                temp = strtok(NULL,"/");
        }
}
int main(){
        char path[] = "/fs/lost+found/df/er/te";
        char *name = path_val(path);
        printf("\n name : %s \n",name);
        free(name);
        return 0;
}

答案 1 :(得分:1)

获取所需路径的另一种方法是一次删除一个结束路径组件,然后将新路径与所需路径进行比较。实现此逻辑的简单方法是通过一个函数来获取原始路径的副本,删除最后一个组件,并与所需路径进行比较。该副本会保留原始路径字符串以供使用,因为strtoksetting '/' to '\0'会修改原始字符串。 main中的简单while循环也可以很容易地放在path_trim函数中。 (虽然在main()中防止内存泄漏更容易)这是一个简单的实现。它可以使用或不使用路径末尾的尾部斜杠:

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

/** Trims last path component from full path string.
*  Returns everything prior to last '/' as path.
*/
char *path_trim (char *path) 
{
    size_t len = strlen (path);     /* get length of original path      */
    char *p = path + (len - 2);     /* set pointer to next to last char */
                                    /* (prevents break on trailing '/') */
    while (p-- >= path)             /* work backwards through path      */
        if (*p == '/') {            /* if *p == '/', set value = null   */
            *p = 0;
            break;                  /* break */
        }

    return (p > path) ? p : path;   /* if no '/' return original path   */
}

int main () {

    char path[] = "/fs/lost+found/df/er/te";
    char *name = strdup (path);         /* duplicate path to modify      */

    printf ("\n path : %s\n", path);    /* output original path          */

    while (strcmp (name, "/fs/lost+found") != 0) /* while name not path  */
    {
        path_trim (name);           /* trim one path component from end  */
        if (strlen (name) < 1)      /* path < 1, not found, break        */
            break;
    }

    printf(" name : %s \n\n",name); /* print final path name found       */
    if (name) free (name);          /* free memory allocate to name      */

    return 0;
}

<强>构建

gcc -Wall -Wextra -o bin/pval pathval.c

<强>输出:

$ ./bin/pval

 path : /fs/lost+found/df/er/te
 name : /fs/lost+found

Valgrind摘要:

==16802== HEAP SUMMARY:
==16802==     in use at exit: 0 bytes in 0 blocks
==16802==   total heap usage: 1 allocs, 1 frees, 24 bytes allocated
==16802==
==16802== All heap blocks were freed -- no leaks are possible
==16802==
==16802== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)