c++-function-atoi

c++ atoi 设计与实现

http://www.cplusplus.com/reference/cstdlib/atoi/

转换一个string 为 数字

声明:

int atoi(const char* str);

解析传入的c-string 内容,并转换其内容为整数,最终结果,以int 的形式返回。

 

函数开始将丢弃尽可能多的空白字符(通过isspace判断),直到第一个非空白字符。之后,从这个字符开始,取一个可选的+或-符号,紧接着读取尽可能多的10进制数字,并转换为对应的数值。

 

该字符串可以在形成整数的字符之后包含其他额外的字符,额外的字符将被忽略。

如果第一个非空白字符不是数字或者+/-符号,或者,如果字符串为空,或者只包含了空白字符,不会执行任何的转换,最终将返回0

参数:

str: c-string ,以一个整数开始。

返回值

成功的话,函数以int形式返回被转换的整数。

如果值超过了int 表示的范围,其行为未定义。如果这种情况存在,参考strtol 的接口设计。

数据冲突

只会访问str 表示的数据

异常:

不会抛出异常。

如果str 不指向合法的c-string,或超出int 表示的范围,将导致未定义的行为。

 

strtol

http://www.cplusplus.com/reference/cstdlib/strtol/

long int strtol (const char* str, char** endptr, int base);

转换string 为long integer

以base 指定的进制转换str 指定的内容为数字,最终结果以long int 返回。

如果endptr 不为空,函数设置endptr 为该数字的最后一个字符的后一个字符。

函数首先跳过尽可能多的空格;依据base 指定的进制,取尽可能多的合法字符,并转换他们为数字;最后,endptr 指向第一个非法字符。

 

如果base 为0,语法类似于整数常量的语法,如下:

1. 可选的符号字符(+或-)

2. 可选的前缀,指示8、16进制(0或0x或0X)

3. 十进制数字序列(如果未指定基本前缀)或八进制或十六进制数字(如果存在特定前缀)

如果base 为[2,36],合法数字为'0'到 'z/Z'(36使用)。可能有+/-前缀,如果base 为16,可选的0x或者0X

参数

str

c-string 参数,包含要转换的数字内容

endptr

如果非空,包含转换的字符串的下一个字符串

base

进制。如果为0,将取决于str 的内容(10,8,16)

返回值

成功,以long int 返回转换得到的数字

如哦没有合法的转换,返回0,

如果超范围了,返回LONG_MAX或者 LONG_MIN,errno 被设置为ERANGE

 

数据竞争

str 指向的数组,如果endptr 非空,将被设置

异常

不主动抛出异常

如果str 指向非法c-string,或endptr 不指向合法对象,将产生未定义行为。

 

errno

https://en.cppreference.com/w/cpp/error/errno

errno 是一个用于错误处理的预定义宏,c++11 之前定义为静态函数,c++11开始定义为一个线程局部变量。

标准库中的一些函数,通过向errno 设置正整数来指示错误。通常,这些值是一些预定义的宏,定义在cerrno 中,以字符E 开始,之后有一些大写的字母或数字。

 

程序启动时,errno 被设置为0,尽管无论是否发生错误,都允许库函数将正整数写入errno,但库函数绝不会在errno 中存储0

 

c++ 的方式std::stoi

https://en.cppreference.com/w/cpp/string/basic_string/stol

//int std::stoi(const string & _Str, size_t * _Idx = nullptr, int _Base = 10)

//C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29333\include\string

 


// sto* NARROW CONVERSIONS
inline int stoi(const string& _Str, size_t* _Idx = nullptr, int _Base = 10) {
    // convert string to int
    int& _Errno_ref  = errno; // Nonzero cost, pay it once
    const char* _Ptr = _Str.c_str();
    char* _Eptr;
    _Errno_ref      = 0;
    const long _Ans = _CSTD strtol(_Ptr, &_Eptr, _Base);

    if (_Ptr == _Eptr) {
        _Xinvalid_argument("invalid stoi argument");
    }

    if (_Errno_ref == ERANGE || _Ans < INT_MIN || INT_MAX < _Ans) {
        _Xout_of_range("stoi argument out of range");
    }

    if (_Idx) {
        *_Idx = static_cast<size_t>(_Eptr - _Ptr);
    }

    return static_cast<int>(_Ans);
}

stack over flow 上的一些讨论:

https://stackoverflow.com/questions/194465/how-to-parse-a-string-to-an-int-in-c

enum STR2INT_ERROR { SUCCESS, OVERFLOW, UNDERFLOW, INCONVERTIBLE };

STR2INT_ERROR str2int (int &i, char const *s, int base = 0)
{
    char *end;
    long  l;
    errno = 0;
    l = strtol(s, &end, base);
    if ((errno == ERANGE && l == LONG_MAX) || l > INT_MAX) {
        return OVERFLOW;
    }
    if ((errno == ERANGE && l == LONG_MIN) || l < INT_MIN) {
        return UNDERFLOW;
    }
    if (*s == '\0' || *end != '\0') {
        return INCONVERTIBLE;
    }
    i = l;
    return SUCCESS;
}

关于c++ 字符串转int 执行效率的一些讨论

https://tinodidriksen.com/2010/02/cpp-convert-string-to-int-speed/

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值