strtok与strtok_r源码

来源:互联网 发布:陕西旅游实时数据 编辑:程序博客网 时间:2024/05/29 15:09

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;
}

原创粉丝点击