特殊字符长度

时间:2015-05-18 20:30:24

标签: c special-characters

我今天发现了一些非常奇怪的东西。

在上面的代码中,我看到utrlen(&eot)(utrlen == strlen)等于2,utrlen(&etx) == 1

最好的部分:当我用etx交换声明顺序时,utrlen(&eot) == 1utrlen(&etx) == 2 ......

char            **get_ukey_string()
{
  static char   eot = 0x4;
  static char   etx = 0x3;
  static char   *ukey_string[NB_UKEY] = {
    "\b", "\r", "[B", "\0", "\n", "[D", "[C", "[A", &etx, &eot
  };

  return (ukey_string);
}

t_hashtable     *new_ukey_htable(int fd)
{
  char          **ukey_string;
  t_hashtable   *htable;
  t_hashnode    *hnode;
  char          *key;
  unsigned int  i;
  size_t        size;

  if ((htable = new_hashtable(NB_UKEY)) == NULL)
    return (NULL);
  ukey_string = get_ukey_string();
  i = 2;
  while (i < NB_UKEY + 2)
    {
      key = ukey_string[i - 2];
      size = utrlen(key);
      if (((hnode = new_hashnode(sutrdup(key, size), size, i)) == NULL)
          || htable->add_node(htable, hnode))
        {
          delete_hashtable(htable);
          return (NULL);
        }
      ++i;
    }
  return (htable);
}

有谁知道为什么?

2 个答案:

答案 0 :(得分:3)

eot和etx是char,而不是char *,所以你不能对它们应用strlen,因为没有null终止符。

答案 1 :(得分:2)

strlen函数(为什么要调用它utrlen?)接受const char*类型的参数。该参数必须指向字符串的初始字符,定义为“由第一个空字符终止并包含第一个空字符的连续字符序列”。

使用声明的strlen对象的地址调用char是合法的;地址类型char*(指向char的指针)匹配要传递给strlen的所需类型。但它不是字符串的初始字符,因此行为未定义。

实际上,strlen将从您为其提供地址的char对象开始,并进行迭代直至看到空字符'\0'

如果char对象恰好具有值'\0',它会立即找到它并返回0 - 这不是特别有用。

如果它有其他值,strlen将尝试扫描内存中不属于对象的字节。结果是未定义的行为。

不要那样做。