strtok与strtok_r源码

strtok与strtok_r是字符串操作经常会用到的两个函数. 下面是它们的源码. 但是这两个函数都有个缺点, 如果字符串为Test1:Test2::Test3:::Test4:::: 则用::作为分割符号仍然能得到Test1 Test2 Test3 Test4四个字符串.

另外由于传入的第一个参数会被修改('/0'), 故使用前需要拷贝原来字符串以备份.

 

char * strtok(char *string, const char * ctrl)
{
  assert(ctrl != NULL);
  char *str;
  static char *token = 0;
  unsigned char map[32];
  int count = 0;
  for (; count < 32; count++)
  {
    map[count] = 0;
  }

  do
  {
    map[*ctrl++ >> 3] |= (1 << (7 & *ctrl));    //由于字符串最大为256, 除以8, 正好为32;
  } while (*ctrl);

  if (string != NULL)
  {
    str = string;
  }
  else
  {
    str = token;
  }

  while(*str && (map[*str] & (1 << (7 & *str)))) str++;  // 跳过字符串可能含有的匹配部分

  for (; *str; str++)
  {
    if (*str && map[*str] & (1 << (7 & *str)))
    {
      *str++ = '/0';  //截断字符串并往往下移动一个字符串.
      break;
    }
  }

  nexttoken = str;    // 保存位置

  if (str == string)
  {
    return NULL;
  }
 
  return str;
}

bool is_character_in_string(char ch, char *string)
{
  assert(string != NULL);
  while (*string)
  {
    if (ch == *string++)
    {
      return true;
    }
  }

  return false;
}

char * tortok_r(char *string, const char *ctrl, char **savePtr)
{
  assert(ctrl != NULL);

  if (string == NULL)
  {
    string = *savePtr;
  }

  while (*string && is_character_in_string(*string, ctrl)) string++;   // 跳过可能含有的匹配部分

  if (!*string)
  {
    return NULL;
  }

  char *token = string;
  while(*string && !is_character_in_string(*string, ctrl)) string++;   // 找到匹配部分

  if (!*string)
  {
    *savePtr = string;
  }
  else
  {
    *string = '/0';         // 截断字符串
    *savePtr = string + 1;  // savePtr指向下一个字符串
  }

  return token;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值