2007年8月31日 星期五

C Function - split

ANSI C 中缺少類似 PHP 中的 split 處理函式,在字串處理中卻又常使用,以下是簡單範例

str:欲被 split 的字串

delim:用來分隔的字串

num:設定分隔出來的子字串最大的數目,如果 <1則不限制

傳回值為一儲存分割結果的字串陣列,當陣列中的值為 NULL表示結束。

char** split(char* str, const char* delim, int num){
char** tab=NULL;
int flag;
unsigned int pos_num=0, pos_num2=0;
unsigned long int i, j, k, str_leng, delim_leng, *pos;

str_leng = strlen(str);
delim_leng = strlen(delim);

pos = (unsigned long int*)malloc(sizeof(unsigned long int)*(int)(str_leng/delim_leng+1));

i = 0;

while(i<=(str_leng - delim_leng)) {
flag = 0;
for(j=0; j<delim_leng; j++) {
if(str[i+j]!=delim[j]) { flag=-1; break; }
flag = 1;
}
if(flag == 1) {
i = i + delim_leng;
pos[pos_num++] = i - delim_leng;
if(num<1) continue;
else if(num==pos_num) break;
} else i++;
}

if(pos_num==0) {
tab = (char **)malloc(sizeof(char*)*2);
tab[0] = (char *)malloc(sizeof(char)*(str_leng+1));
strcpy(tab[0], str);
tab[1] = NULL;
return tab;
}

tab = (char **)malloc(sizeof(char*)*pos_num);

if(pos[0]!=0) {
tab[pos_num2] = (char *)malloc(sizeof(char)*pos[0]);
for(i=0, j=0; i<pos[0]; i++, j++) tab[pos_num2][j] = str[i];
tab[pos_num2][j] = '\0';
pos_num2++;
}

for(i=1; i<pos_num; i++) {
if(pos[i] - (pos[i-1] + delim_leng) >0) {
tab[pos_num2] = (char *)malloc(sizeof(char)*(pos[i] - (pos[i-1] + delim_leng)) + 1 + 1);
for(j=pos[i-1] + delim_leng, k=0; j<pos[i]; j++, k++) tab[pos_num2][k] = str[j];
tab[pos_num2][k] = '\0';
pos_num2++;
}
}

if((pos[pos_num-1] + delim_leng - 1) < str_leng - 1) {
tab[pos_num2] = (char *)malloc(sizeof(char)*(pos[pos_num-1] + delim_leng - 1) + 1 + 1);
for(j=pos[pos_num - 1] + delim_leng, i=0; j<str_leng; j++, i++) tab[pos_num2][i] = str[j];
tab[pos_num2][i] = '\0';
pos_num2++;
}

tab[pos_num2] = NULL;
return tab;
}

使用範例

char **tab;
int i;

tab = split("1,2,3,4,5,6,7,8,9,0", ",", -1);
i = 0;
while(tab[i]!=NULL) printf("%d = %s =\n", i, tab[i++]);

沒有留言: