【问题标题】:Taking an index out of const char* argument从 const char* 参数中取出索引
【发布时间】:2017-01-24 10:42:10
【问题描述】:

我有以下代码:

int some_array[256] = { ... };

int do_stuff(const char* str)
{
   int index = *str;
   return some_array[index];
}

显然,上面的代码在某些平台上会导致错误,因为 *str 实际上可以为负数。

于是我想到了两种可能的解决方案:

  1. 将值转换为赋值 (unsigned int index = (unsigned char)*str;)。

  2. 改为传递const unsigned char*

编辑:这个问题的其余部分没有得到处理,所以我把它移到了一个新线程。

【问题讨论】:

  • 为什么将索引作为字符串传递?你想达到什么目的?
  • 真的吗?为什么要将char * 传递给函数,并将其指向的内容用作静态数组的索引?
  • ".. *str 实际上可以是负数" 不应该是一个错误。如果调用代码没有正确处理它,那么bug就在那里,不在这个sn-p中。
  • @Raw N - 即使是稍微不错的技术也会有所改进。
  • @qrdl:字符串操作的查找表是一种非常重要的实现技术。

标签: c++ c string


【解决方案1】:

char 的签名确实与平台有关,但您知道char 的值与unsigned char 的值一样多,并且转换是单射的。因此,您绝对可以将值转换为将查找索引与每个字符相关联:

unsigned char idx = *str;
return arr[idx];

您当然应该确保arr 至少有UCHAR_MAX + 1 元素。 (当sizeof(unsigned long long int) == 1 时,这可能会导致热闹的边缘情况,幸运的是这种情况很少见。)

【讨论】:

  • 其实协议使用八位字节,所以只需要保证数组有256个元素即可。 UCHAR_MAX>255 是否无关紧要,因为任何可能的输入都不能包含这样的值。
  • @MSalters:是的,我要说的是——如果你有关于预期输入的信息,你可以将查找表限制为那个(并断言)。
【解决方案2】:

字符可以有符号或无符号,具体取决于平台。无符号范围的假设是导致您的错误的原因。

您的do_stuff 代码不会将const char* 视为字符串表示形式。它将它用作查找表中的字节大小的索引序列。因此,在do_stuff 内的字符串字符上强制输入unsigned char 并没有错(即使用您的解决方案#1)。这使char 的重新解释为本地化到do_stuff 函数实现的索引。

当然,这假设您的代码的其他部分确实将 str 视为 C 字符串。

【讨论】:

    猜你喜欢
    • 2018-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多