Splitting the full file name into parts

I am creating a function that will split the full name of the unix file (e.g. / home / earlz / test.bin) into separate parts. I have a function, and it works fine for the first two parts, but after that it creates an erroneous result ...

strlcpy_char will copy the string using the term as a terminator, as well as 0. If it ends with a term, then the term will be the last character of the string, then null.

returns the string length 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) } } 

I use this code to verify it:

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

When I try something like "/home/test.bin", it works correctly, outputting

  / home
 /test.bin

But when I try "/home/earlz/test.bin", I get

  / home
 / earlz
 / arlz

Does anyone see a problem in my code as I searched, but I just don't see any problem.

Also, before you say “but there is a library for this,” I do it in the kernel of the operating system, so I hardly have a standard library. I have only parts of string.h and really, what about this for the standard.

+4
source share
7 answers

You overwrite current_i instead of adding it as you go along the path.

So,

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

really should be

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

I think you need to keep track of your current_i for i> 1, since the maximum value returned from strlcpy has no idea where you are in the general line of the file. it makes sense?

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

You do not need to do something like

 tocurrent_i += strlcpy_char... 

instead

 tocurrent_i = strlcpy_char... 
+2
source

Do you need to re-enter your code? If you do not use strtok, it is in 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); 

Sorry for not commenting on your code :)

0
source

If you use Glib, g_strsplit very nice and easy to use.

0
source

This is how i do it

 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
source

Try something like the code that I have below.

If you need implementations of standard C functions (e.g. strchr ()), try koders.com or just google for 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; } 
0
source

Source: https://habr.com/ru/post/1286115/


All Articles