将std :: string(保证数字)转换为unsigned char

时间:2014-09-25 16:12:39

标签: c++ casting stringstream unsigned-char

我已经为铸造字符串创建了一个模板来执行不同的数据类型,并且当数据类型是无符号字符时它会出现问题。

template<class TYPE>
bool TryParse(const std::string value, TYPE &out)
{
    std::istringstream iss(value);
    iss >> out;

    if (iss.fail())
    {
        return false;
    }

    return true;
}

问题是istringstream会将它看到的第一个字符视为char,而不是将其视为数字字符串。因此,如果我传递&#34; 255&#34;的值,则返回的值将为&#39; 2&#39;。

最佳解决方案是将out变量转换为unsigned int,执行操作,然后再次转换回来吗?

1 个答案:

答案 0 :(得分:3)

我建议有一个特别适用于unsigned char个案例的重载,因为你需要使用中间类型。

bool TryParse(const std::string & value, unsigned char & out)
{
    std::istringstream iss(value);
    unsigned int i;
    iss >> i;

    if (iss.fail()) { return false; }

    // The less-than-min check is technically redundant because both i and out
    // are unsigned, but it makes me feel better having it there.  It will become
    // necessary for the "signed char" overload, anyway.
    if (i > std::numeric_limits<unsigned char>::max() ||
        i < std::numeric_limits<unsigned char>::min()) {
            throw std::overflow_error();
            // Or you could "return false" instead, if that makes more sense.
    }

    out = static_cast<unsigned char>(i);
    return true;
}

您可以为signed char使用几乎相同的功能。 (只需将每个unsigned替换为signed。)

我不建议在模板中使用中间类型,因为您需要使用尽可能广泛的类型,并且没有任何一种类型可以使用。例如,unsigned long long intsigned long long int不兼容,反之亦然 - 这些类型都不会与floatdouble兼容。拥有一个直接使用所请求类型的基本模板,对于有问题的类型(例如char)的重载是正确的方法。


请注意,我已将value参数更改为对const字符串的引用,因为这意味着调用者无需无理由地复制字符串。我建议你也改变你的模板功能。