字符串指针的赋值问题
想用c编写一个函数split(str,cut_char,sn)
str是原字符串,cut_char是分隔字符,sn是分割后的数组。比如split( "ABCD**EFGH**IJ ", "** ",&sn),那么sn[0]=ABCD,sn[1]=EFGH,sn[2]=IJ
谢谢达人啊
int split(char *s,char *cut_char,char ***sn)
{ char **seg=0;
char *p,*q;
int scnt=0;
p=q=s;
while(*q)
{
if(strncmp(q,cut_char,strlen(cut_char))==0)
{
scnt++;
seg=(char**)realloc(seg,scnt*sizeof(char*));
seg[scnt-1]=(char*)calloc((q-p+1),sizeof(char));
strncpy(seg[scnt-1],p,q-p);
p=q+strlen(cut_char);
q+=strlen(cut_char)-1;
}
q++;
}
if(p!=q)
{
scnt++;
seg=(char**)realloc(seg,scnt*sizeof(char*));
seg[scnt-1]=(char*)calloc((q-p+1),sizeof(char));
strncpy(seg[scnt-1],p,q-p);
}
*sn = seg;
return scnt;
};
这个是我写的一个,返回的scnt是数组长度。大家看看有什么问题
[解决办法]
这个是strtok里代码,你可以参考下
char * strtok_r(
const char *sr,
const char *delim,
char **lasts
)
{
char* s = new char[strlen(sr) + 1];
strcpy(s, sr);
char *spanp;
int c, sc;
char *tok;
if (s == NULL && (s = *lasts) == NULL)
return (NULL);
/*
* Skip (span) leading delimiters (s += strspn(s, delim), sort of).
*/
cont:
c = *s++;
for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
if (c == sc)
goto cont;
}
if (c == 0) {/* no non-delimiter characters */
*lasts = NULL;
return (NULL);
}
tok = s - 1;
/*
* Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
* Note that delim must have one NUL; we stop if we see that, too.
*/
for (;;) {
c = *s++;
spanp = (char *)delim;
do {
if ((sc = *spanp++) == c) {
if (c == 0)
s = NULL;
else
{
s[-1] = 0;
}
*lasts = s;
return (tok);
}
} while (sc != 0);
}
}
[解决办法]
这个是完全版:)
/*
* Copyright (c) 1988 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
*This product includes software developed by the University of
*California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS ' ' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <string.h>
char *
_DEFUN (strtok_r, (s, delim, lasts),
register char *s _AND
register const char *delim _AND
char **lasts)
{
register char *spanp;
register int c, sc;
char *tok;
if (s == NULL && (s = *lasts) == NULL)
return (NULL);
/*
* Skip (span) leading delimiters (s += strspn(s, delim), sort of).
*/
cont:
c = *s++;
for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
if (c == sc)
goto cont;
}
if (c == 0) {/* no non-delimiter characters */
*lasts = NULL;
return (NULL);
}
tok = s - 1;
/*
* Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
* Note that delim must have one NUL; we stop if we see that, too.
*/
for (;;) {
c = *s++;
spanp = (char *)delim;
do {
if ((sc = *spanp++) == c) {
if (c == 0)
s = NULL;
else
s[-1] = 0;
*lasts = s;
return (tok);
}
} while (sc != 0);
}
/* NOTREACHED */
}
#undef __STRICT_ANSI__
#include <string.h>
#include <_ansi.h>
#include <reent.h>
#ifndef _REENT_ONLY
char *
_DEFUN (strtok, (s, delim),
register char *s _AND
register const char *delim)
{
return strtok_r (s, delim, &(_REENT-> _new._reent._strtok_last));
}
#endif
[解决办法]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int split(char *str, char *cut_char, char **sn)
{
int i = 0;
int j = 0;
char *p = str;
char *q = cut_char;
char temp[10];
int flag = 0;
while ( *p != '\0 ' )
{
while ( *q != '\0 ' )
{
if ( *p != *q )
q++;
else //找到分割符
{
q++;
flag = 1;
}
}
if ( *q == '\0 ' && !flag)
temp[i++] = *p;
if ( flag == 1 ) //把分割符之前的copy到指针数组sn里
{
temp[i] = '\0 ';
strcpy(sn[j++], temp);
i = 0;
flag = 0;
}
p++;
q = cut_char;
}
if( *p == '\0 ' )
{
temp[i] = '\0 ';
strcpy(sn[j++], temp);
}
return j;
}
int main()
{
char *str = "ABCD**EFGH**IJ ";
char *step = "** ";
char *sn[10];
int i, j;
for (i=0; i <10; i++)
sn[i] = (char *)malloc(10);
j = split(str, step, sn);
for (i=0; i <j; i++)
printf( "sn[%d]=%s\n ", i, sn[i]);
for (i=0; i <10; i++)
free(sn[i]);
return 0;
}
[解决办法]
上面的程序存在点问题,就是字符串里有连续分割符出现的时候。。。
char *str = "ABCD**EFGH**IJ ";
char *step = "** ";
str里连续出现step中字符的时候,最后得出的指针数组下标不连续,会把空串也打印出来
出来了。。
象上面那个例子。最后出现的sn[]显示为:
sn[0] = ABCD
sn[1] =
sn[2] = EFGH
sn[3] =
sn[4] = IJ
想了半天也没解决这个问题,下面的哪位帮忙看下怎么改。。。。