分解字符串,将关键字符替换为字符串终止符’\0’.当该函数在 s中字符串发现 delim 中包含的字符时,会将该字符改为’\0’。第一次调用时 s必须为所求字符串。之后则将 s设置成NULL,该函数能够自动识别并且从上一次截取的字符串之后开始继续替换截取功能。每次调用成功则返回指向被分割出片段的指针。
//
// strtok.c
//
// Created by Lancer on 15-1-13.
// Modified by Lancer on 15-1-14.
// 主要修改:
// 1. 将 _ifNUll 这个全局指针改为在 myStrtok函数中作用的静态指针,更符合模块化编程要求
// 2. 将一个 if-else 语句改为三目判断语句,简化程序
// 3. 规范化所有的注释
// 4. 初始化各个参数
//
#include <stdio.h>
#define MAXSIZE 50 //输入串最大长度
//#undef strFirstNot
//#undef strFirstIn
char *myStrtok (char *s, const char *delim);
int strFisrtNot(const char *s, const char *delim); //用于返回 s 字符串中第一个不在 delim 中字符的下标
char *strFirstIn(const char *s1,const char *s2);// s1 第一次出现 s2 中含有的字符时,返回该字符位置。
//char *_ifNull; //一个全局指针
int main()
{
char myInputNo1[MAXSIZE] = "abc,123,xyz"; //一个输入字符串,用于myStrtok的 s 参数
char myInputNo2[MAXSIZE] = ",abc,lancer,123q456,,xyz,,,567p89,ppaaaqqdd"; //另一个输入字符串,用于myStrtok的 s 参数
char *s1 = NULL, *s2 = NULL;
char *suit1 = ",", *suit2 = ",pq";
//suit1 = ",";
//suit2 = ",pq";
//处理串一,并逐个输出token
printf ("\nThe 1st string you input is %s And your match string is [ %s ]\n", myInputNo1, suit1);
printf("The 1st result is: \n");
//s = myInputNo1;
s1 = myStrtok (myInputNo1, suit1);
while (s1 != NULL)
{
printf ("\t%s\n", s1);
s1 = myStrtok (NULL, suit1);
}
//处理串二,并逐个输出token
printf ("\nThe 2nd string you input is %s And your match string is [ %s ]\n", myInputNo2, suit2);
printf("The 2nd result is: \n");
s2 = myStrtok (myInputNo2, suit2);
while (s2 != NULL)
{
printf ("\t%s\n", s2);
s2 = myStrtok (NULL, suit2);
}
return 0;
}
/**
*函数描述:分解字符串,将关键字符替换为字符串终止符’\0’.当该函数在 s 中字符串发现 delim 中包含的字符时,会将该字符改为’\0’.
第一次调用时 s 必须为所求字符串。之后则将 s 设置成NULL,该函数能够自动识别并且从上一次截取的字符串之后开始继续替换截取功能。每次调用成功则返回指向被分割出片段的指针。
*
*@param s:待分解的字符串
*@param delim:分隔符字符串。
*@return: 返回每个token的头指针
*/
char *myStrtok(char *s, const char *delim)
{
char *sBegin = NULL, *sEnd = NULL;
static char *_ifNull;
sBegin = s?s:_ifNull;
//若 s 为空且静态指针 _ifNull 为空,返回空指针。
if (!sBegin)
{
return (NULL);
}
sBegin += strFisrtNot(sBegin, delim); //将sBegin指向第一个非匹配域的字符位置
if (*sBegin == '\0') //若第一个非匹配域字符为字符串终止,则将全局指针设为空,并返回空
{
_ifNull = NULL;
return (NULL);
}
sEnd = strFirstIn (sBegin, delim);//找到该串中第一个属于delim中字符的位置
if (sEnd && *sEnd != '\0')
{
*sEnd++ = '\0';
}
_ifNull = sEnd; //将指针指向下一个串的第一个位置
return (sBegin);
}
/**
*函数描述:找出 s 字符串中第一个不在 delim 中字符的下标,并返回
*
*@param s:待分解的字符串
*@param delim:分隔符字符串。
*@return: 返回第一个不在delim中字符的下标。为整型。
*/
int strFisrtNot(const char *s, const char *delim)
{
const char *ps; //临时指针
const char *pd; //临时指针,指向匹配域
int count = 0; //用于计数
//找到第一个不匹配的字符位置,返回下标
for(ps = s; *ps != '\0'; ++ps)
{
for (pd = delim; *pd != '\0'; ++pd)
{
if (*ps == *pd)
{
break;
}
}
if (*pd == '\0')
{
return count;
}
++count;
}
return count;
}
/**
*函数描述:扫描 s1,当遇到第一个 s2 中的字符时,返回该字符的位置
*
*@param s1:字符串一,用于查找
*@param s2:字符串二,用于匹配
*@return: 返回s1中出现第一个s2中字符时字符的指针。
*/
char *strFirstIn(const char *s1,const char *s2)
{
const char *sc1, *sc2; //临时指针
//找到第一个匹配的,返回指针
for (sc1 = s1; *sc1 != '\0'; ++sc1)
{
for (sc2 = s2; *sc2 != '\0'; ++sc2)
{
if (*sc1 == *sc2)
{
return (char *)sc1;
}
}
}
return (NULL);
}