2009-06-12 17 views
4

Ich erstelle eine Funktion, die einen vollständigen Unix-Dateinamen (wie /home/earlz/test.bin) in seine einzelnen Teile aufteilen wird. Ich habe eine Funktion, und es funktioniert für die ersten beiden Teile perfekt, aber danach produziert es fehlerhafte Ausgabe ...Teilen eines vollständigen Dateinamens in Teile

Strlcpy_char wird eine Zeichenfolge mit Begriff als Terminator, sowie 0. kopieren, wenn es ist terminiert mit term, dann ist term das letzte Zeichen der Zeichenkette, dann null.

kehrt trg String-Länge ...

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

Ich benutze diesen Code zu testen:

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

Wenn ich etwas versuchen, wie "/home/test.bin" es richtig funktioniert

 
/home 
/test.bin 

Ausgeben Aber wenn ich versuche, "/home/earlz/test.bin" bekomme ich

 
/home 
/earlz 
/arlz 

Jeder sieht das Problem in meinem Code, wie ich gesucht habe, aber ich sehe kein Problem.

Bevor Sie sagen, "aber es gibt eine Bibliothek dafür", mache ich das in einem Betriebssystemkernel, also habe ich kaum eine Standardbibliothek. Ich habe nur Teile von string.h und das ist wirklich Standard.

Antwort

4

Sie überschreiben current_i, anstatt es zu addieren, während Sie den Pfad durchlaufen.

So

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

sollte wirklich

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

Muss der Code erneut eingegeben werden? Wenn nicht strtok verwenden, ist es in strings.h

ist
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); 

Es tut uns allerdings nicht auf Ihren Code zu kommentieren :)

+0

Ich glaube nicht, dass ich wie die Umsetzung das Gefühl, dass ich (wie ich hätte, oder es Hafen von irgendwo sonst auf meinem Kernel zu kompilieren) Außerdem muss mein Code einspringenden werden .. es geht um Teil des Dateisystemtreibers zu sein, der von allen Arten von Prozessen zu einem unbekannten Zeitpunkt verwendet wird ... – Earlz

0

Wenn Sie Glib verwenden, g_strsplit ist sehr schön und einfach zu bedienen.

+0

Betriebssystemkern. Keine Bibliotheken implementiere ich selbst nicht. – Earlz

2

Ich glaube, Sie müssen Ihre current_i verfolgen für i> 1, da der maximale Wert aus der strlcpy hat zurück keine Ahnung davon, wo Sie sind in die gesamte Dateizeichenfolge. macht das Sinn?

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

Ich denke, Tobiesque traf den gleichen Punkt, während ich die Antwort tippte. Er hat Recht. +1 für ihn. –

2

Sie nicht brauchen, wie etwas zu tun

tocurrent_i += strlcpy_char... 

statt

tocurrent_i = strlcpy_char... 
+0

Ah. Zu spät. +1 zu Tobuesque :) –

0

Dies ist, wie ich tun würde es

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

so etwas wie Probieren der Code, den ich unten habe.

Wenn Sie Implementierungen von Standard-C-Funktionen benötigen (wie strchr()), versuchen Sie es auf koders.com oder googlen Sie einfach nach strchr.c.

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