C++ 如何检查从C++;字符串转换为无符号整数

C++ 如何检查从C++;字符串转换为无符号整数,c++,casting,type-conversion,C++,Casting,Type Conversion,我需要: 1) 查找当前系统上的最大无符号整数值。我没有在极限上找到它。写入无符号整数maxUnsInt=0-1是否安全?我还尝试了unsigned int maxUnsInt=MAX_int*2+1返回正确的值,但编译器显示了有关int溢出操作的警告 2)一旦找到,检查C++字符串(我知道它是由数字组成的)超过了我的系统上的最大无符号int值。< /P> 我的最终目标是使用atoi将字符串转换为无符号整数,当且仅当它是有效的无符号整数时。我更喜欢只使用标准库。根据您不需要计算它,只需使用适当

我需要:

1) 查找当前系统上的最大无符号整数值。我没有在极限上找到它。写入
无符号整数maxUnsInt=0-1是否安全?我还尝试了
unsigned int maxUnsInt=MAX_int*2+1
返回正确的值,但编译器显示了有关int溢出操作的警告

2)一旦找到,检查C++字符串(我知道它是由数字组成的)超过了我的系统上的最大无符号int值。< /P> 我的最终目标是使用atoi将字符串转换为无符号整数,当且仅当它是有效的无符号整数时。我更喜欢只使用标准库。

根据您不需要计算它,只需使用适当的常量,在这种情况下应为
UINT\u MAX

几张钞票

与C++相比,这似乎更像是一种C方式,但既然你说你想使用<代码> ATOL 我就坚持下去。如约阿希姆建议的那样,C++将使用<代码>数字限制>代码>。但是C++标准也定义了类C宏/定义,所以使用它应该是安全的。p>

也希望如果是C++方式,最好使用<代码> StrugSuth(这是标准C++库的一部分)进行转换。 最后,我故意不发布显式代码解决方案,因为它看起来像是家庭作业,您现在应该可以从这里开始了。

对各种数字类型有限制:

unsigned int maxUnsInt = std::numeric_limits<unsigned int>::max();
中应该有一个
#define UINT_MAX
;我会的 如果没有,我会非常惊讶。否则,这是有保证的 即:

将导致最大值。在C++中,你也可以使用
std::numeric\u limits::max()
,但在C++11之前, 这不是一个积分常量表达式(可能是,也可能是) 不成问题)

不保证是任何东西(至少在一个系统上,
MAX\u INT==UMAX\u INT

关于检查字符串,最简单的解决方案是 要使用
strtoul
,请验证
errno
和返回值:

bool
isLegalUInt( std::string const& input )
{
    char const* end;
    errno = 0;
    unsigned long v = strtoul( input.c_str(), &end, 10 );
    return errno == 0 && *end == '\0' && end != input.c_str() && v <= UINT_MAX;
}
bool
islegaluant(标准::字符串常量和输入)
{
字符常量*结束;
errno=0;
无符号长v=strtoul(input.c_str(),&end,10);

return errno==0&&*end='\0'&&end!=input.c_str()&&v Check out and.thanking.numeric_limits似乎有效,但stoi返回的是整数或长整数,而不是无符号整数。这并不能解决我的问题:我希望在字符串不超过最大无符号整数值的情况下转换字符串。请检查“另见"链接页面上的部分。还要记住,如果你想先手动检查字符串,那么你就要在字符串上做两个循环,本质上就是将字符串转换为一个数字两次。哈哈,现在人们似乎错过了盘子上给出的答案,因为你只指向了盘子的一边。@Bedo有
stoul
,它们是将
变为无符号长字符串
;之后,只需检查
UINT_MAX
。或者如果您不喜欢异常(它们很可能不适合此处)无论如何,检查溢出的任何东西都必须转换,所以你最好使用它的转换结果,而不是浪费时间用<代码> AutUI 。11是未定义的行为,尽管我知道的所有实现都正确地执行了它。其次,即使使用
“0”
,您也可能(几乎可以肯定)以
成功
错误告终。如果您想进行错误检查,没有理由使用
atoi
(而且几乎没有任何理由不进行错误检查)。检查溢出的最简单方法是使用
strtoul
,这将直接返回转换后的值。(在C++11之前,使用
istringstream
的转换在溢出的情况下具有未定义的行为,尽管我所知道的所有实现从一开始就遵循C++11的规则,并在溢出时设置
failbit
)@James饶了我吧伙计。我只是指出了他在查找最大值时的错误,并告诉了一种转换方法。我不想重复其他人的答案,Joachim告诉了我关于
std::stoi
。我也不想把这方面的确切答案作为家庭作业。然而,我认为
stringstream
会抛出异常或错误过流时出错。我的错,谢谢你指出这一点!那么作为c++11之前最好的方法,我建议使用
atol
,手动检查它是否返回
0
。实际上没有任何情况下
atoi
atol
是可接受的解决方案。你无法检测到它们的错误。它们只是y是由于历史原因出现的,不应该在现代代码中使用。啊,是的,我读错了。如果
ato?
系列出现溢出,该值是未定义的。那么我想在c++11之前是不可能的,因为
stringstream
也未定义。至少使用标准库('因为你总是可以编写自己的输入读取器。)我说的对吗?
ato?
系列的问题是它们无法报告错误。当我实现它们时(在20世纪80年代初的某个时候),我确实检测到溢出,并像处理stdtol一样处理它,因此这当然是可能的,但仍然无法确定它们处理了多少个字符,以及是否都是这些字符。至于为什么不幸的是
strtoul
stoul
在他的
unsigned int
大小不同的情况下不起作用s是一个
无符号的long
(不幸的是,缺少
stou
仍然是一个)。当然仍然是+1,但值得注意。它们当然有效。您只需将结果分配给
unsigned int u = -1;
unsigned int u = 2 * MAX_INT + 1;
bool
isLegalUInt( std::string const& input )
{
    char const* end;
    errno = 0;
    unsigned long v = strtoul( input.c_str(), &end, 10 );
    return errno == 0 && *end == '\0' && end != input.c_str() && v <= UINT_MAX;
}