假设我有一个字符串和一个由bool组成的向量,根据字符串中的字符,我想将相应的向量索引设置为true。
std::vector<bool> is_present(256, false);
for (int i = 0; i < str.size(); ++i)
{
is_present[str[i]] = true;
}据我所知,该标准并没有定义字符的带符号。根据平台的不同,可能是签名的,也可能是未签名的。在大多数平台上,有符号字符将是8位二进制数(-128到127),无符号字符将是8位无符号整数(0到255)。
如果是这样的话,str[i]是否有可能返回一个负数并导致is_present[str[i]]中的内存故障?或者char被类型转换为vector<bool>::size_type,它是unsigned,因此不会出现问题?
另外,使用vector<bool> is_present(pow(2, CHAR_BIT)), false)比硬编码256更好吗?
发布于 2012-01-13 08:30:10
如果您希望确定值,请始终将char强制转换为unsigned char。
您可以输入1u << CHAR_BIT来获得所需的大小。
std::vector<bool> is_present(1u << CHAR_BIT, false);
for (int i = 0; i < str.size(); ++i)
{
is_present[static_cast<unsigned char>(str[i])] = true;
}发布于 2012-01-13 08:31:47
如果你真的想这样做,我会使用std::numeric_limits<std::string::char_type>::min(),然后从值中减去它,以确保它总是从0开始,无论字符类型的范围是什么:
#include <string>
#include <vector>
#include <limits>
int main() {
const std::string str = "hello world";
std::vector<bool> is_present(256, false);
for (std::string::size_type i = 0; i < str.size(); ++i) {
is_present[static_cast<int>(str[i]) - std::numeric_limits<std::string::value_type>::min()] = true;
}
}不过,对于向量的初始大小,您也需要使用max()和min()。
发布于 2012-01-13 08:39:30
整数之间的类型升级首先将值扩展到适当的大小,然后可能会更改类型。这是<cctype>函数最常见的错误之一,人们会“忘记”这些函数只能与正值一起使用,并且char可能会导致负值。例如,在支持ISO-Latin 1(ISO/IEC8859-1:1998)的语言环境中,尝试将我的名字大写将在签署char的平台上产生灾难性的结果。
处理这个问题的正确方法是使用static_cast<unsigned char>(c),或者,假设你已经包含了<cinttypes>,像std::uint8_t(c)这样的东西。当然,要确定char数组的适当大小,可以使用std::numeric_limits<unsigned char>::max():使用pow()有点过分。通常,当您需要2的幂时,您宁愿使用移位运算符(在unsigned类型上),而不是pow()。
https://stackoverflow.com/questions/8844339
复制相似问题