代码2、在主函数里分配堆空间:
int splitString2(const char *buf1, char c, char **myp, int *count)
{
char *p=NULL, pTmp=NULL;
int tmpCount=0;
//p和pTmp初始化
p=pTmp=buf1;
do{
p=strchr(p, c);
if(p!=NULL)
{
if(p-pTmp>0)
{
strncpy(myp[tmpCount], pTmp, p-pTmp);
myp[tmpCount][p-pTmp]='\0';
tmpCount++
p=pTmp=p+1;
}else{
break;
}
}
}while(*p!='\0');
*count=tmpCount;
return 0;
}// splitString2 end.
void main()
{
int ret=0, i =0
char *p1="abcdef,acccd,eeee,aaaa,e3eeeee,sssss,";
char cTem = ',' ;
char **p=NULL;
int nCount=0;
p=(char**)malloc(sizeof(char *) * 10);
if(p==NULL)
{
return ;
}
for(i=0;i<10;i++)
{
p[i]=(char)malloc(30*sizeof(char));
}
ret=splitString2(p1, cTem, p, &nCount);
if(ret !=0)
{
printf("func splitString2 err: %d \n", ret);
return ret;
}
for(i=0;i<nCount;i++)
{
printf("%s \n", p[i]);
}
for(i=0;i<nCount;i++)
{
free(p[i]);
p[i]=NULL;
}
free(p);
} // end main
代码3、在被调函数里分配堆内存空间,对内存空间进行精确控制
需要扫描两遍,第一遍求出多少个逗号,为分配第一维的行数提供依据。
对于一个入口,多个出口的函数,可以使用goto语句跳转到同一个异常处理出口。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
1、定义两个指针变量,指向字符串开始位置;
2、让一个字符串移动,两个字符串形成差值;
3、在两个字符串差值之间找需要的字符串;
4、再次让两个字符串对齐,准备下一次检索;
*/
void memFree(char ***p, int lines) // 内存释放函数
{
char **p2=NULL;
int i=0;
if(p==NULL)
{
return;
}
p2=*p;
if(p2==NULL)
{
return;
}
for(i=0;i<lines; i++)
{
if(p2[i]!=NULL)
{
free(p2[i]);
p2[i]==NULL;
}
}
if(p2 != NULL)
{
free(p2);
}
*p=NULL;
}
int splitString4(const char *mys, char cTmp, char ***p3, int *count)
{
int tmpCount=0;
int ret=0;
char *myp=NULL;
char *pTmp=NULL;
char **p2=NULL;
if(mys==NULL || p3==NULL || count == NULL)
{
ret = -1;
printf("func splitString4() err: %d (mys==NULL || p3==NULL || count == NULL)\n", ret);
//return ret;
goto END;
}
//遍历,给出逗号的个数
//定义两个指针变量,指向字符串开始位置;
myp=pTmp=mys;
do
{
myp=strchr(myp, cTmp);
if(myp != NULL)
{
if(myp - pTmp>0)
{
tmpCount++;
myp++;
pTmp=myp;
}
}else
{
break;
}
}while(*myp != '\0');
/*if(tmpCount==0)
{
ret=0;
goto END;
}*/ //暂时不考虑没有逗号的情况
//开辟空间,截取字符串,赋值
p2=(char **)malloc(sizeof(char *) * tmpCount);
if(p2==NULL)
{
ret=-2; //申请二级指针内存失败代号
printf("func splitString4() err: %d (sizeof(char *) * tmpCount) \n", ret);
goto END; //
}
memset(p2, 0, tmpCount * sizeof(char *)); // 申请成功之后,将p2的所有的内存空间置为0,可避免野指针。在后期释放所指向的二级指针的时候,可判断当前指针是否是NULL,避免错误释放
*count=tmpCount;
tmpCount=0;
myp=pTmp=mys;
int len=0;
do
{
myp=strchr(myp, cTmp);
if(myp != NULL)
{
if(myp - pTmp>0)
{
len=myp - pTmp+1;//+1: for storing '\0';
p2[tmpCount]=(char*)malloc(sizeof(char)*len);
if(p2[tmpCount]==NULL)
{
ret=-3;
printf("func splitString4() err: %d (sizeof(char)*len) \n", ret);
goto END;
}
//内存分配成功,拷贝
strncpy(p2[tmpCount], pTmp, myp - pTmp);
p2[tmpCount][myp - pTmp]='\0';
tmpCount++;
myp++;
pTmp=myp;
}
}else
{
break;
}
}while(*myp != '\0');
//异常处理
END:
if(ret !=0) //失败
{
//memFree(&p2, tmpCount);
memFree(&p2, *count); // 由于p2指向的内存空间都事先置为0,即p2所指向的“指针数组”在未挂载内存时,都为NULL,若挂在了内存,则不为NULL。利用这样一个特性,可以使用统一的内存释放策略,即将所有的指针都判断是否是NULL并释放非NULL的指针指向的空间
} else
{
*p3=p2;
}
return ret;
}
int main()
{
char *s="aaaaa,bbbbb,ccccc,";
char c=',';
char **p=NULL;
int nCount=0, ret=0,i=0;
ret=splitString4(s, c, &p, &nCount);
if(ret!=0)
{
printf("func splitString4() err: %d \n", ret);
return ret;
}
for(i=0;i<nCount;i++)
{
printf("p[%d]: %s \n", i, p[i]);
}
memFree(&p, nCount);
return 0;
}