2009-06-12 37 views
4

我正在创建一个将完整的unix文件名(如/home/earlz/test.bin)分割为各个部分的函数。我有一个函数,它适用于前两个部分完美,但之后,它会产生错误的输出...将完整的文件名分割成部分

strlcpy_char将复制一个字符串使用术语作为终止符,以及0. 如果它是以term结尾,那么term将是字符串的最后一个字符,然后是null。

回报TRG字符串长度...

int strlcpy_char(char *trg,const char *src,int max,char term){ 
    int i; 
    if(max==0){return 0;} 
    for(i=0;i<max-1;i++){ 
      if(*src==0){ 
        *trg=0; 
        return i; 
      } 
      if(*src==term){ 
        *trg=term; 
        trg++; 
        *trg=0; //null terminate 
        return i+1; 
      } 
      *trg=*src; 
      src++; 
      trg++; 
    } 
    *trg=0; 
    return max; 
} 

int get_path_part(char *file,int n,char *buf){ 
    int i; 
    int current_i=0; 
    //file is assumed to start with '/'so it skips the first character. 
    for(i=0;i<=n;i++){ 
      current_i++; 
      current_i=strlcpy_char(buf,&file[current_i],MAX_PATH_PART_SIZE,'/'); 
      if(current_i<=1){ //zero length string.. 
        kputs("!"); //just a debug message. This never happens with the example 
        return -1; //not enough parts to the path 
      } 
    } 
    if(buf[current_i-1]=='/'){ 
      return 1; //is not the last part 
    }else{ 
      return 0; //is the last part(the file part) 
    } 
} 

我使用此代码来测试它:

 kputs("test path: "); 
     kgets(cmd); 
     kputs("\n"); 
     char *tmp=malloc(256); 
     int i=0; 
     get_path_part(cmd,i,tmp); 
     kputs(tmp); 
     kputs("\n"); 
     i=1; 
     get_path_part(cmd,i,tmp); 
     kputs(tmp); 
     kputs("\n"); 
     i=2; 
     get_path_part(cmd,i,tmp); 
     kputs(tmp); 
     kputs("\n"); 

当我尝试像 “/home/test.bin” 它的工作原理正确的输出

 
/home 
/test.bin 

但是当我尝试“/home/earlz/test.bin”我得到

 
/home 
/earlz 
/arlz 

任何人都可以在我的代码中看到问题,因为我一直在寻找,但我只是看不到任何问题。另外,在你说“但有一个库”之前,我在操作系统内核中这样做,所以我几乎没有标准库。我只有string.h的一部分,真的是标准的。

回答

4

您覆盖current_i而不是在您浏览路径时添加它。

所以

current_i++; 
current_i=strlcpy_char(buf,&file[current_i],MAX_PATH_PART_SIZE,'/'); 

确实应该

current_i += strlcpy_char(buf,&file[current_i+1],MAX_PATH_PART_SIZE,'/'); 
0

您的代码是否需要重新进入? 如果不使用strtok的,它是在strings.h

STRTOK(P) 

NAME 
     strtok, strtok_r - split string into tokens 

SYNOPSIS 
     #include <string.h> 

     char *strtok(char *restrict s1, const char *restrict s2); 

     char *strtok_r(char *restrict s, const char *restrict sep, 
       char **restrict lasts); 

对不起,如果您使用的油嘴在你的代码虽然:)

+0

我不认为我觉得实现我自己(因为我会,或端口它从别的地方来编译我的内核) 此外,我的代码必须被重入..这是怎么回事在任何未知的时间成为各种进程使用的文件系统驱动程序的一部分... – Earlz 2009-06-12 01:18:45

0

不评论,g_strsplit是非常好的,易于使用。

+0

操作系统内核。没有图书馆我不执行自己。 – Earlz 2009-06-12 01:21:22

2

我认为你需要跟踪你的current_i为I> 1,因为最大值从编写的strlcpy返回有没有你在的想法整个文件字符串。是否有意义?

current_i=strlcpy_char(buf,&file[current_i],MAX_PATH_PART_SIZE,'/'); 
+0

我认为Tobiesque在输入答案的同时达到了同样的效果。他是对的。 +1给他。 – 2009-06-12 01:35:30

2

不要你需要做的是这样

tocurrent_i += strlcpy_char... 

,而不是

tocurrent_i = strlcpy_char... 
+0

啊。太晚了。 +1到Tobuesque :) – 2009-06-12 01:36:40

0

这是我会做它

char ** split_into_parts(char *path) { 
    char ** parts = malloc(sizeof(char *) * 100); 
    int i = 0; 
    int j = 0; 

    if (*path == '/') { 
    path++; 
    } 

    parts[0] = 0; 
    while (*path) { 
    if (*path == '/') { 
     parts[i][j] = 0; 
     i++; 
     parts[i] = 0; 
     j = 0; 
    } else { 
     if (parts[i] == 0) { 
     parts[i] = malloc(sizeof(char) * 100); 
     } 
     parts[i][j] = *path; 
     j++; 
    } 
    path++; 
    } 
    parts[i+1] = 0; 

    return parts; 
} 
0

试着这么做我有下面的代码。

如果您需要标准C函数(如strchr())的实现,请尝试koders.com或仅适用于strchr.c的Google。

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

const char *NextToken(const char *pStart, char chSep, char *pToken, size_t nTokMax) 
{ 
    const char *pEnd; 
    size_t nLength; 

    /* set output to empty */ 
    *pToken=0; 

    /* make sure input is OK */ 
    if (!pStart || *pStart!=chSep) 
     return NULL; 

    /* find end of token */ 
    pEnd = strchr(pStart+1, chSep); 
    if (pEnd) 
     nLength = pEnd - pStart; 
    else 
     nLength = strlen(pStart); 

    if (nLength >= nTokMax) /* too big */ 
     return NULL; 

    strncpy(pToken, pStart, nLength); 
    pToken[nLength] = 0; 

    return pEnd; 
} 

int main() 
{ 
    #define BUFFSIZE 256 
    char cmd[BUFFSIZE]; 
    char tmp[BUFFSIZE]; 
    const char *pStart=cmd; 
    int i=0; 

    puts("test path: "); 
    fgets(cmd, BUFFSIZE, stdin); 
    puts(""); 

    do { 
     pStart = NextToken(pStart, '/', tmp, BUFFSIZE); 
     if (tmp[0]) 
      puts(tmp); 
    } while (pStart); 
    return 0; 
}