std::atoi() 和 std::stoi 有啥区别?
Posted
技术标签:
【中文标题】std::atoi() 和 std::stoi 有啥区别?【英文标题】:What is the difference between std::atoi() and std::stoi?std::atoi() 和 std::stoi 有什么区别? 【发布时间】:2013-12-14 13:34:11 【问题描述】:atoi
和 stoi
有什么区别?
我知道,
std::string my_string = "123456789";
为了将该字符串转换为整数,您必须执行以下操作:
const char* my_c_string = my_string.c_str();
int my_integer = atoi(my_c_string);
C++11 提供了一个简洁的替代方案:
std::string my_string = "123456789";
int my_integer = std::stoi(my_string);
1)。两者还有其他区别吗?
2)。在效率和性能方面哪个更好?
3)。哪个更安全?
【问题讨论】:
您可能想阅读例如thisstd::stoi
reference 并将其与 this std::atoi
reference 进行比较。
哦,顺便说一句,std::atoi
不是 std::stoi
对应的 C 函数,而是 std::strtol
,我推荐 atoi
。
你实际上是在 strtok 点上
【参考方案1】:
1)。两者还有其他区别吗?
我发现std::atoi()
是一个可怕的函数:它在出错时返回零。如果您将零视为有效输入,则您无法判断转换期间是否存在错误或输入是否为零。那很糟糕。参见例如How do I tell if the c function atoi failed or if it was a string of zeros?
另一方面,相应的 C++ 函数会在出错时抛出异常。您可以正确地将错误与零区分开来作为输入。
2)。在效率和性能方面哪个更好?
如果你不关心正确性,或者你确定你不会有零作为输入,或者你认为这是一个错误,那么,也许 C 函数 可能 更快(可能是由于缺乏异常处理)。这取决于您的编译器、您的标准库实现、您的硬件、您的输入等。最好的方法是测量它。但是,我怀疑差异(如果有的话)可以忽略不计。
如果您需要快速(但丑陋的 C 风格)实现,the most upvoted answer 对How to parse a string to an int in C++? 的问题似乎是合理的。但是,除非绝对必要,否则我不会采用这种实现方式(主要是因为不得不与 char*
和 \0
终止混淆)。
3)。哪个更安全?
参见第一点。
除此之外,如果您需要使用char*
并注意\0
的终止,您更容易出错。 std::string
使用起来更容易、更安全,因为它会处理所有这些事情。
【讨论】:
这是非常可靠的建议。关于你的第一点(返回值与错误代码),我检查了 atoi 的手册页,它说:It is equivalent to: (int)strtol(str, (char **)NULL, 10);
,从 strtol 的手册页中,第二个参数:(Thus, if *first_param is not
\0' 但是** second_param 是\0' on return, the entire string was valid.)
。因此,似乎将 strtol 与第二个参数一起使用会比 atoi 更好,以避免您在第 1 点中描述的问题。 strtol 可以包含在 stdlib.h 中。
@NickDesaulniers 是的,如果您检查我的答案中链接的问题(“如何在 C++ 中将字符串解析为 int?”),您会发现最受好评的答案也使用了 @987654334 @。但是,除非万不得已,否则我不会走那条路;由于我在回答中给出的原因,我不会使用strtol
。
@NickDesaulniers 顺便感谢您的评论:原来我的回答已经过时了。接受的答案现在不同了,所以我的答案是指错误的答案。
@Ali “另一方面,对应的 C++ 函数”——你的意思是 atoi
不在 std::
命名空间中?
@DavidDoria 我的意思是std::stoi。以上是关于std::atoi() 和 std::stoi 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章
cygwin g++ std::stoi“错误:‘stoi’不是‘std’的成员