在C++中将字符串转换为短整型

10

我查阅了如何将字符串转换为short,但大多数是关于如何将字符串转换为整数的。虽然我想在那些帖子下留言提问,但我没有足够的声望。我的目标是将一个字符串转换为一个short,因为这个数字永远不会超过三或低于零,并且使用short可以节省内存(据我所知)。

需要明确的是,这里不是指ASCII码。

另外一件事,我想要做的是检查将字符串转换为short是否失败,因为我将用到来自用户输入的字符串。

我知道可以使用while循环实现,但如果在C++中有内置函数来完成此操作,它与while循环同样或更加高效,我很乐意听取建议。


1
short s; std::istringstream strm("100"); strm >> s; 这个不行吗? - timrau
1
“shorts save memory”这句话的真正问题在于,你为什么认为需要节省内存呢? - user657267
2
@user657267,我对程序效率着迷,因为我是一个完美主义者。 - Logan Kling
1
@LarryK “我对程序效率的追求是因为我太过于完美主义” 那么,您是否编写了代码以确保您的规则得以维护,即“数字永远不应超过三或低于零”? - PaulMcKenzie
2
@LarryK 就像所有事情一样,存在权衡取舍,除非你使用长数组/结构体并且缓存起作用,否则使用 shortint 之间的性能差异可能很小。你应该从使用 int 开始,只有在分析表明需要时才考虑其他类型。编程时,你应该首先考虑 你自己 的效率,真的值得花费时间去纠结那些几乎没有影响的问题吗? - user657267
显示剩余5条评论
4个回答

14

基本上,由于未知原因,缺少了一个std :: stos函数,但是您可以轻松地自己编写。使用std :: stoi将其转换为int,根据例如std :: numeric_limits<short>给出的short边界检查值,如果超出范围,则抛出std :: range_error ,否则返回该值。

如果您已经安装了Boost库,则可以使用boost :: lexical_cast 方便起见,但否则我会避免使用它(主要是因为冗长和库依赖性,而且它也有点低效)。

早期的boost :: lexical_cast因不太高效而闻名,我认为这是因为它在内部基于字符串流,但正如在此处的评论中报道的那样,现代版本比通过字符串流转换更快,而且比通过scanf 更快。


1
一个示例代码会非常有帮助,尤其是使用while或do while循环来捕获范围错误的代码。 - Logan Kling
3
@LarryK:我不会为你捕鱼或者给你准备食材。鉴于你提到想让别人替你完成这些事情,你非常需要学会自己捕鱼和处理食材。最好的方法就是去亲身尝试。 - Cheers and hth. - Alf
1
关于 lexical cast 的效率,你的解释非常清晰!这是我一直在关注的问题。谢谢。 - Logan Kling
@LarryK:嗯,碰巧我对那个括号里的话说错了:情况已经改变了。所以我把它标记为删除,并添加了更加最新的信息。;-) - Cheers and hth. - Alf
1
有另一篇SO帖子,其中一个人对所有不同的字符串转整数例程进行了基准测试。 - M.M
显示剩余2条评论

5

一种高效的方法是使用boost::lexical_cast

short myShort = boost::lexical_cast<short>(myString);

你需要安装boost库以及以下的头文件:#include <boost/lexical_cast.hpp> 如果转换失败,应该捕获bad_lexical_cast异常:
    try
    {
        short myShort = boost::lexical_cast<short>(myString);
    }
    catch(bad_lexical_cast &)
    {
        // Do something
    }

词法转换的效率与 short s; std::istringstream strm("100"); strm >> s; 相比如何? - Logan Kling
1
@LarryK lexical_cast 的速度大约比其他方法快20倍(http://www.boost.org/doc/libs/1_57_0/doc/html/boost_lexical_cast/performance.html)。 - Drew Dormann

3
您还可以使用ssprintf%hi格式说明符进行操作。
示例:
short port;
char szPort[] = "80";

sscanf(szPort, "%hi", &port);

我其实几周前才了解这些修饰符,但是非常感谢你的回答!我发现hhh修饰符非常有用,不仅仅适用于ssprintf() - Larrimus

1

数字不应超过三或少于零

如果您真的非常需要节省内存,那么这也适合使用char(无论char是有符号还是无符号)。

另一个“极端”的技巧:如果您可以相信没有像“002”这样的奇怪东西,那么您拥有的就是一个单字符字符串。如果是这种情况,并且您真的非常需要性能,请尝试:

char result = (char)( *ptr_c_string - '0' );

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接