首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

字符串指针的赋值有关问题

2012-02-23 
字符串指针的赋值问题想用c编写一个函数split(str,cut_char,sn)str是原字符串,cut_char是分隔字符,sn是分

字符串指针的赋值问题
想用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
想了半天也没解决这个问题,下面的哪位帮忙看下怎么改。。。。

热点排行