从 const char* 参数中取出索引
Posted
技术标签:
【中文标题】从 const char* 参数中取出索引【英文标题】:Taking an index out of const char* argument 【发布时间】:2017-01-24 10:42:10 【问题描述】:我有以下代码:
int some_array[256] = ... ;
int do_stuff(const char* str)
int index = *str;
return some_array[index];
显然,上面的代码在某些平台上会导致错误,因为 *str 实际上可以为负数。
于是我想到了两种可能的解决方案:
将值转换为赋值 (unsigned int index = (unsigned char)*str;
)。
改为传递const unsigned char*
。
编辑:这个问题的其余部分没有得到处理,所以我把它移到了一个新线程。
【问题讨论】:
为什么将索引作为字符串传递?你想达到什么目的? 真的吗?为什么要将char *
传递给函数,并将其指向的内容用作静态数组的索引?
".. *str 实际上可以是负数" 不应该是一个错误。如果调用代码没有正确处理它,那么bug就在那里,不在这个sn-p中。
@Raw N - 即使是稍微不错的技术也会有所改进。
@qrdl:字符串操作的查找表是一种非常重要的实现技术。
【参考方案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 字符串。
【讨论】:
以上是关于从 const char* 参数中取出索引的主要内容,如果未能解决你的问题,请参考以下文章
求助:error C2664: “CreateWindowExW”: 不能将参数 3 从“const char [8]”转换为“LPCWSTR”
error C2664: “StrCmpW”: 不能将参数 2 从“const char [12]”转换为“PCWSTR”
const char* const* p 参数在 g++ 中编译但不是 gcc
用常量参数定义 main (const int argc, const char * const argv[])?
error C2664: “int CWnd::MessageBoxW(LPCTSTR,LPCTSTR,UINT)”: 无法将参数 1 从“const char [9]”转换为“LPCTSTR”