一个关于特定分隔符分割字符串的问题(用strtok并不理想)

bigzhizhi 2007-08-29 12:45:24
比如一个字符串
char GPS_INFO[]="$GPRMC,112720.000,A,3639.2868,N,11659.8396,E,,,200305,,*12"
用","为分隔标志将里面的指定参数信息提取出来,C语言怎么实现?

希望以如下函数形式实现
char *strSplict(char *str,const char *seps,int pos)
其中str是原字符串,seps为分隔符,pos为指定位置.
比如 info3=strSplict(GPS_INFO,",",3)应为"3639.2868";

我尝试过strtok,但很有意思的是遇到",,,"这样的空段它自作主张的给去掉了(我的意思是就算空茅坑它也必须得给我留着,好让我跟序号一一对上)
...全文
633 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
bigzhizhi 2007-08-29
  • 打赏
  • 举报
回复
应该是应用很广泛的一个问题,但我老找不到一个实用的例子.
sxlengwa 2007-08-29
  • 打赏
  • 举报
回复
char *strSplict(char *str,const char *seps,int pos)
lz这个函数原形要求必须在函数里分配一段内存,调用它的函数必须在调用之后释放内存,不然会容易造成内存泄露。

char *strSplict(char *dest, const char *str,const char *seps,int pos)
感觉还是这样好点,在外面分配内存,将缓冲区指针传进去,写入结果,并返回。
bigzhizhi 2007-08-29
  • 打赏
  • 举报
回复
xugang_2001(幽明天竹)兄:
需要说明的是,其实楼主这种问题可以换一个方式来解决,楼主在给GPS_INFO赋值的时候为什么不把本来是空的地方强制写一个预定值(比如*NULL*),然后用strtok就可以优美的解决了而不用自己写那么多累赘的代码.

我也想啊,但这东东是直接从设备上读出来的,改不了哦(哭)
bigzhizhi 2007-08-29
  • 打赏
  • 举报
回复
啊,等了好半天,终于有人来帮我看了(热泪满眶),我先好好看一下.
cceczjxy 2007-08-29
  • 打赏
  • 举报
回复
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char * strSplict(const char * str, const char * seps, int pos)
{
int pos1=0,pso2=0,len1=0,len2=0;
int count=0;
if(pos<0)return NULL;
char *ptr,*res;
ptr=str;
while((pos1=strcspn(ptr,seps))!=strlen(ptr))
{
count++;
if(count==pos+1)
{
res=(char*)malloc(pos1+1);
strncpy(res,ptr,pos1);
return res;
}
ptr+=pos1;
ptr+=1;
}

return ( NULL );
}

int main()
{
char *ptr="$GPRMC,112720.000,A,3639.2868,N,11659.8396,E,,,200305,,*12";
char *seps=",";
int i;
printf("%s\n",ptr);
for(i=0;i<13;i++)
printf("%d %s\n",i,strSplict(ptr,seps,i));
}
xugang_2001 2007-08-29
  • 打赏
  • 举报
回复
花了半个小时研究了一下, 发现用strtok的确不能解决问题,遇到空会跳过,我自己写了一个,自己也测试过了,可以解决问题:

char* strSplict(char *str,const char *seps,int pos)
{
int iLen = 0;
int iStart = 0;
int iEnd = 0;
char* token;
char strText[100];
::memset(strText, 0, sizeof(strText));

if (pos == 0)
{
strcpy(strText, strtok(str, seps));
}
else
{
for (int i = 0; i<strlen(str); ++i)
{
if (str[i] == *seps)
{
iStart = iEnd;
iEnd = i;

if (iLen == pos)
{
if (iEnd-iStart-1 > 0)
{
strncpy(strText, str+iStart+1, iEnd-iStart-1);
}

break;
}

iLen++;
}
}
}


//token = strtok( str, seps ); // C4996
// // Note: strtok is deprecated; consider using strtok_s instead
// while( token != NULL )
// {
// // While there are tokens in "string"
// printf( " %s\n", token );

// // Get next token:
// token = strtok( NULL, seps ); // C4996
// }


return strText;
}

需要说明的是,其实楼主这种问题可以换一个方式来解决,楼主在给GPS_INFO赋值的时候为什么不把本来是空的地方强制写一个预定值(比如*NULL*),然后用strtok就可以优美的解决了而不用自己写那么多累赘的代码.

//token = strtok( str, seps ); // C4996
// // Note: strtok is deprecated; consider using strtok_s instead
// while( token != NULL )
// {
// // While there are tokens in "string"
// printf( " %s\n", token );

// // Get next token:
// token = strtok( NULL, seps ); // C4996
// }
wlk 2007-08-29
  • 打赏
  • 举报
回复
/*
得到"|"分割节点值,首位不为"|"
*/
char *GetSubStr(const char * sBuffer,int iNum)
{
static char srBuffer[10240];
int i=0,j=0,iNo=0;

memset(srBuffer,0,sizeof(srBuffer));
for (i=0; i<strlen(sBuffer); i++)
{
if(i>strlen(sBuffer) || iNo > iNum) break;
if (sBuffer[i] == '|')
{
iNo++;
continue;
}
else
{
if (iNo == iNum)
{
srBuffer[j] = sBuffer[i];
j++;
}
}
}
return srBuffer;
}
类似的例子.楼主应该可以用的
bigzhizhi 2007-08-29
  • 打赏
  • 举报
回复
有人帮忙再看一下吗?
bigzhizhi 2007-08-29
  • 打赏
  • 举报
回复
WizardK兄:
你输出的好像是指定位置到结尾的字符串了吧?
我要的是指定位置的那中间一段
还有别的办法吗?
WizardK 2007-08-29
  • 打赏
  • 举报
回复
错了,应该这么写
char * strSplict(const char * str, const char * seps, int pos)
{
char * ret = (char *)str;
int index = 0;
int strlength = strlen( str );
int sepslength = strlen( seps );

while (true)
{
if (ret = strstr( ret, seps ))
ret += sepslength;
else
break;
if ( ret >= str + strlength)
break;
if ( ++index == pos )
return ret;
}

return ( NULL );
}
sxlengwa 2007-08-29
  • 打赏
  • 举报
回复
/*
和楼主要求长的优点不一样,呵呵
dest : 目标缓冲区
str : 待分割字符串
seps : 分隔符
pos : 位置
*/
char *strSplict(char *dest, const char *str,const char seps,int pos)
{
char *tmp = dest;
int count = 0;
assert(dest != NULL && str != NULL);
if (pos < 0)
{
pos = 0;
}
while (count < pos)
{
if(*str++ == seps)
{
count++;
}
}
while (*str && *str != seps)
{
*dest++ = *str++;
}
*dest = '\0';
return tmp;
}
WizardK 2007-08-29
  • 打赏
  • 举报
回复
char * strSplict(const char * str, const char * seps, int pos)
{
int position = 0;
int index = 0;
int strlength = strlen( str );
int sepslength = strlen( seps );

while (true)
{
position = strcspn( str + position, seps ) + position + sepslength;
if ( position >= strlength)
break;
if ( ++index == pos )
return (char *)( str + position);
}

return ( NULL );
}

69,381

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧