c++用什么方法把字符串(char *)解析成int?健壮和清晰的错误处理是一个加分项(而不是返回零)。
当前回答
这是比atoi()更安全的C方式
const char* str = "123";
int i;
if(sscanf(str, "%d", &i) == EOF )
{
/* error */
}
c++与标准库stringstream:(感谢CMS)
int str2int (const string &str) {
stringstream ss(str);
int num;
if((ss >> num).fail())
{
//ERROR
}
return num;
}
使用boost library:(感谢jk)
#include <boost/lexical_cast.hpp>
#include <string>
try
{
std::string str = "123";
int number = boost::lexical_cast< int >( str );
}
catch( const boost::bad_lexical_cast & )
{
// Error
}
编辑:修正了stringstream版本,以便它处理错误。(感谢CMS和jk对原文的评论)
其他回答
这是比atoi()更安全的C方式
const char* str = "123";
int i;
if(sscanf(str, "%d", &i) == EOF )
{
/* error */
}
c++与标准库stringstream:(感谢CMS)
int str2int (const string &str) {
stringstream ss(str);
int num;
if((ss >> num).fail())
{
//ERROR
}
return num;
}
使用boost library:(感谢jk)
#include <boost/lexical_cast.hpp>
#include <string>
try
{
std::string str = "123";
int number = boost::lexical_cast< int >( str );
}
catch( const boost::bad_lexical_cast & )
{
// Error
}
编辑:修正了stringstream版本,以便它处理错误。(感谢CMS和jk对原文的评论)
我喜欢丹的回答,尤其是因为他避免了例外。对于嵌入式系统开发和其他低级别的系统开发,可能没有适当的Exception框架可用。
增加了一个有效字符串后的空白检查…这三行
while (isspace(*end)) {
end++;
}
还增加了对解析错误的检查。
if ((errno != 0) || (s == end)) {
return INCONVERTIBLE;
}
这是完整的功能..
#include <cstdlib>
#include <cerrno>
#include <climits>
#include <stdexcept>
enum STR2INT_ERROR { SUCCESS, OVERFLOW, UNDERFLOW, INCONVERTIBLE };
STR2INT_ERROR str2long (long &l, char const *s, int base = 0)
{
char *end = (char *)s;
errno = 0;
l = strtol(s, &end, base);
if ((errno == ERANGE) && (l == LONG_MAX)) {
return OVERFLOW;
}
if ((errno == ERANGE) && (l == LONG_MIN)) {
return UNDERFLOW;
}
if ((errno != 0) || (s == end)) {
return INCONVERTIBLE;
}
while (isspace((unsigned char)*end)) {
end++;
}
if (*s == '\0' || *end != '\0') {
return INCONVERTIBLE;
}
return SUCCESS;
}
你可以使用c++标准库中的a stringstream:
stringstream ss(str);
int x;
ss >> x;
if(ss) { // <-- error handling
// use x
} else {
// not a number
}
流状态将被设置为失败 当遇到非数字时 正在读取一个整数。
有关c++中错误处理和流的陷阱,请参阅流陷阱。
从c++ 17开始,你可以从<charconv>头文件中使用std::from_chars。
例如:
#include <iostream>
#include <charconv>
#include <array>
int main()
{
char const * str = "42";
int value = 0;
std::from_chars_result result = std::from_chars(std::begin(str), std::end(str), value);
if(result.error == std::errc::invalid_argument)
{
std::cout << "Error, invalid format";
}
else if(result.error == std::errc::result_out_of_range)
{
std::cout << "Error, value too big for int range";
}
else
{
std::cout << "Success: " << result;
}
}
另外,它还可以处理其他进制,比如十六进制。
如果你有c++ 11,现在合适的解决方案是<string>中的c++整数转换函数:stoi, stol, stoul, stoll, stoull。当给出不正确的输入时,它们会抛出适当的异常,并在底层使用快速和小型的strto*函数。
如果您被c++的早期版本所困扰,那么在实现中模拟这些函数将是向前可移植的。
推荐文章
- 未定义对静态constexpr char的引用[]
- 在c++中,restrict关键字是什么意思?
- c++中类似于java的instanceof
- include_directories和target_include_directories在CMake中的区别是什么?
- 转换JSON字符串到JSON对象c#
- std::make_pair与std::pair的构造函数的目的是什么?
- 如何追加一个字符到std::字符串?
- 为什么要在c++中使用嵌套类?
- 如何处理11000行c++源文件?
- 使用g++编译多个.cpp和.h文件
- 如何在c++中追加文本到文本文件?
- 在c++中使用"super
- Mmap () vs.读取块
- 什么是不归路?
- 将类代码分离为头文件和cpp文件