相当于atoi
Posted
技术标签:
【中文标题】相当于atoi【英文标题】:equivalent of atoi 【发布时间】:2011-08-13 13:30:45 【问题描述】:是否有一个函数可以替换 c++ 中的 atoi。 我做了一些研究并没有找到任何可以替代它的东西,唯一的解决方案是使用 cstdlib 或自己实现它
【问题讨论】:
为什么需要更换它? @Jesus:atoi
不安全!它不处理无效输入。此外,他还可以使用 boost 提供的更多其他实用程序。
C++ 标准库明确包含 C 标准库,因此<cstdlib>
是 C++ 的完全合法部分。说std::atoi
,如果这让你感觉更好:-)
我同意@Nawaz 的观点,因为atoi
的界面非常糟糕。 strtol
是合适的替代品,不是因为它做了什么不同的事情——它没有,而是因为它有一个界面可以让您检查是否发生了成功的转换。我不太了解@JesusRamos 参数,即您应该编写更多代码来检查您的输入,然后再将其传递给转换函数。编写一个确定是否可以将字符串解析为数字的函数与编写进行该转换的函数一样难吗?在这种情况下,为什么不使用两者兼得的库函数。
@Jesus Ramos:在将int
传递给atoi
之前“验证”它的任务与atoi
本身一样复杂。事实上,虽然可以预先验证输入的 syntax,但如果不进行实际转换,就不可能捕获 overflow。出于这个原因,atoi
是一个“死”函数,在实际代码中没有用处。几乎任何使用atoi
的代码都因为这个原因而被破坏。 C 语言中的字符串到整数的转换一直由strto...
函数专门执行。他们在 C 标准库中没有替代品。
【参考方案1】:
如果你不想使用 Boost,C++11 为字符串添加了std::stoi
。所有类型都有类似的方法。
std::string s = "123"
int num = std::stoi(s);
与atoi
不同,如果无法进行转换,则会引发invalid_argument
异常。此外,如果值超出 int 的范围,则会引发 out_of_range
异常。
【讨论】:
我一直期待在 std::string 上会有to_int
和 to_long
方法,但我想这几乎一样好。【参考方案2】:
boost::lexical_cast
是你的朋友
#include <string>
#include <boost/lexical_cast.hpp>
int main()
std::string s = "123";
try
int i = boost::lexical_cast<int>(s); //i == 123
catch(const boost::bad_lexical_cast&)
//incorrect format
【讨论】:
Armen:boost::lexical_cast
可能会抛出,所以用 try-catch 包围它以使其更完整。
@Nawaz:我已经参考了文档。在这种情况下,不需要 try-catch。但是好的,我会添加它。【参考方案3】:
可以使用Boost函数boost::lexical_cast如下:
char* numericString = "911";
int num = boost::lexical_cast<int>( numericString );
更多信息请见here(最新的 Boost 版本 1.47)。记得适当处理异常。
【讨论】:
【参考方案4】:没有提升:stringstream ss(my_string_with_a_number); int my_res; ss >> my_res;
和 boost 版本一样烦人,但没有额外的依赖。可能会浪费更多的内存。
【讨论】:
boost版不讨厌 这取决于你是否喜欢 C++ 的发展方向 :) 但我们不要污染这个问题。 @Torp:尝试转换std::string s="8978x9"
。您的方法将在不通知您的情况下失败。另一方面,boost::lexical_cast
会抛出异常,你会知道的!正如@Armen 已经说过的那样,提升并不令人讨厌。
在我看来这是“难以管理的复杂”方向 :) 但遗憾的是我不知道有更好的通用替代方案。
为了解决@Nawaz 对此方法可能失败的担忧,您可以在尝试提取其他内容后测试字符串流:char x; if (!(ss >> x)) /*success*/
【参考方案5】:
你没有说为什么atoi
不合适,所以我猜它与性能有关。无论如何,澄清会有所帮助。
使用 Boost Spirit.Qi 大约比 atoi
快一个数量级,至少在 tests done by Alex Ott 中是这样。
我没有参考,但我上次测试时,Boost lexical_cast
比 atoi
慢了大约一个数量级。我认为原因是它构造了一个stringstream,这很昂贵。
更新:Some more recent tests
【讨论】:
推测atoi
是不合适的,因为它的行为给出了一个无效的参数(我相信行为是未定义的)。
MISRA 规则禁止 atoi,因为处理无效转换时的未定义行为。【参考方案6】:
你可以使用函数stoi();
#include <string>
// Need to include the <string> library to use stoi
int main()
std::string s = "10";
int n = std::stoi(s);
要实际编译它,您必须启用 c++11,在 google 上查找如何操作(在 code::blocks 上是:设置 -> 编译器 -> “让 g++ 遵循 C++11 ISO C++ 语言标准”) 如果从终端编译,则必须添加 -std=c++11
g++ -std=c++11 -o program program.cpp
【讨论】:
以上是关于相当于atoi的主要内容,如果未能解决你的问题,请参考以下文章
Google Cloud Endpoints 相当于 API 网关,还是 Endpoints 相当于微服务?
Excel数据清单的列相当于数据库中的______。(1分)