将一个字符串拆分到一个二维数组中。例如:"123,234,345,45678"拆分为"123"、"234"、"345"、"45678"。
#include<stdio.h>
#include<malloc.h>
#include<string.h>
typedef struct array
{
int count; //元素个数 (元素矩阵的高度)
int lenth; //长度(元素矩阵的宽度)
char **item; //指向每个字符串的指针
void (*init)(struct array *); //数组初始化、内存分配
void (*free)(struct array *); //数组内存释放
}Array;
//初始化函数,内存分配
void Array_init(Array *a)
{
int i;
a->item=(char **)malloc(sizeof(char)*a->count);
for(i=0; i<a->count; i++)
a->item[i]=(char *)malloc(sizeof(char)*a->lenth);
};
//内存释放函数
void Array_free(Array *a)
{
int i;
for(i=0; i<a->count; i++) free(a->item[i]);
free(a->item);
};
//拆分函数
Array *split(char *s,char c)
{
int i,j,n=1,lenth;
Array *r;
char *p=s;
r=(Array *)malloc(sizeof(Array));
r->init=Array_init;
r->free=Array_free;
r->count=1; //默认是不需要分割的字符串
r->lenth=0;
lenth=0;
while(*p!='\0')
{
if(*p==c) //一个子串的统计结束
{
r->count++; //子串个数
if(lenth>r->lenth)r->lenth=lenth; //最长的子串长度
lenth=0; //重新开始统计字符个数
}
else lenth++;
p++;
}
if(lenth>r->lenth)r->lenth=lenth;//最后一个子串,也有可能是最长的子串长度
r->init(r);
i=j=0;
p=s;
while(*p!='\0')
{
if(*p!=c) r->item[i][j++]=*p;
else
{
r->item[i][j]='\0';
i++; //下一个字符串
j=0;
}
p++;
}
r->item[i][j]='\0';
return r;
};
int main()
{
int i;
char s[]="123,234,345,45678";
Array *r;
r=split(s,',');
for(i=0; i<r->count; i++)
printf("%s\n",r->item[i]);
r->free(r);
}
程序中结果存储到一个结构Array中:
typedef struct array
{
int count;//元素个数 (元素矩阵的高度)
int lenth;//长度(元素矩阵的宽度)
char **item;//指向每个字符串的指针
void (*init)(struct array *);//函数指针,数组初始化、内存分配
void (*free)(struct array *);//函数指针,数组内存释放
}Array;
成员count记录行数,lenth是最长的串的长度。这样构造成一个字符矩阵,相当于一个字符型的二维数组。每行的地址存储在item数组中,item指向一个动态分配的指针数组。init和free为两个函数指针,指向两个函数,从而使得结构具有“行为”的特征。这类似于一个类的方法,这也是一种面向对象编程方法的模拟。
拆分函数的工作流程如下:
定义一个Array结构指针r,并分配内存。
初始化成员init和free函数指针。
搜索要拆分的字符串s,根据拆分字符c统计子串个数count,同时记录最长的子串长度。调用init分配内存,然后将子串字符逐个存储到对应的子串空间中。Item类似于二维数组的数组名,每个item数组元素都是一个char*指针,指向子串空间的首地址。这是一个典型的动态数组。不过,这里方便起见,程序让所有子串的长度相等,这样符合二维数组的特征。
运行结果如下: