我正在创建一个将完整的unix文件名(如/home/earlz/test.bin)拆分为各个部分的函数。我有一个功能,它适用于前两个部分完美,但之后会产生错误的输出......
strlcpy_char将使用term作为终结符复制字符串,以及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的一部分,真的是关于它的标准。
答案 0 :(得分: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,'/');
答案 1 :(得分:2)
我认为你需要跟踪你的current_i for i&gt; 1,因为从strlcpy返回的最大值不知道你在整个文件字符串中的位置。它有意义吗?
current_i=strlcpy_char(buf,&file[current_i],MAX_PATH_PART_SIZE,'/');
答案 2 :(得分:2)
你不需要做像
这样的事情tocurrent_i += strlcpy_char...
而不是
tocurrent_i = strlcpy_char...
答案 3 :(得分: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);
很抱歉没有评论您的代码:)
答案 4 :(得分:0)
如果您使用Glib,g_strsplit
非常好用且易于使用。
答案 5 :(得分: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;
}
答案 6 :(得分:0)
尝试类似我下面的代码。
如果您需要标准C函数的实现(如strchr()),请尝试使用koders.com或只使用谷歌搜索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;
}