我需要编程方面的帮助。程序必须接受一个最终将转为unsigned long的字符串。但是这里有捕获,必须有一个错误捕获器,当你输入十六进制组合和像a!!!!!!
这样的符号时会产生错误,而unsigned long变量必须能够接受并存储大于{{1}的输入这是4294967295
。我试过这段代码:
FFFFFFFF
我的问题是,当我输入char buffer[256];
unsigned long holder;
fgets(buffer,256,stdin);
holder = strtoul (buffer,NULL,16);
(9 F')代替FFFFFFFFF
(8 F')时,持有人仍然会接受FFFFFFFF
,即使它超过了4294967295
。另一件事是,当我结合十六进制和a!!!!!
之类的符号时,fgets
仍然会考虑十六进制A.
你能告诉我一个如何做到这一点的想法吗?如果您对此代码以外的任何其他想法有所了解,请告诉我们。谢谢!
答案 0 :(得分:1)
如果您使用的是“旧C stule字符串”,则可以通过将char *
传递给strtoul
调用来添加额外的检查,以查看“所有字符都已被删除”。
换句话说:
char *end_ptr = NULL;
....
errno = 0;
holder = strtoul(buffer, &end_ptr, 16);
end_ptr
将指向一个超过接受输入的字符,因此如果输入“a !!!!!”,它将指向'!'。
if (end_ptr != '\0') // Should point at "end of string marker".
{
... do something to indicate error.
}
要检测溢出,您必须依赖errno
:
if (errno != 0)
{
... deal with errors here .
}
显然,你可以这样做:
if (errno != 0 || *end_ptr != '\0')
{
.... deal with errors.
}
使用C ++ std:stoul()
函数会抛出异常,例如:
试 { holder = std :: stoul(缓冲区); } 抓住(...) { ......处理错误...... }
将是C ++风格的解决方案。
答案 1 :(得分:1)
因此,如果您查看strtoul
的此文档,您会在Return Value
部分看到此内容:
如果转换后的值超出相应的返回类型范围,则会发生范围错误,并返回ULONG_MAX或ULLONG_MAX。
因此,对于超出范围的检查,您需要与此类似的代码:
if ( ( holder == ULONG_MAX || holder == ULLONG_MAX ) && errno == ERANGE)
对于查看同一文档的a!!!!
案例,您将看到:
这些函数将str_end指向的指针设置为指向解释的最后一个字符后面的字符。如果str_end为NULL,则忽略它。
您目前正在传递NULL
,但如果您传入参数:
char *p;
holder = strtoul (buffer,&p,16);
您现在可以检查*p
是否为NULL终止符,如果是,则处理所有字符,否则您知道自己有问题。
您还可以选择使用stoul
,如果无法执行转换,则会抛出以下异常std::invalid_argument
;如果转换后的值超出结果范围,则会std::out_of_range
类型。
例如,您可以执行以下操作:
std::string str1(n) ;
size_t pos ;
try
{
holder = std::stoul( str1, &pos, 16 ) ;
}
catch( std::invalid_argument e )
{
std::cout << "Invalid argument" << std::endl ;
}
catch ( std::out_of_range e )
{
std::cout << "Out of range" << std::endl ;
}
pos
将是处理的最后一个字符的索引,在您的情况下,pos != str1.length()
然后它无法处理整个字符串并且您有问题。
答案 2 :(得分:0)
正如其他海报所说 - 如果你拥有它,请使用stoul
。
如果不这样做,您可以执行以下操作:
std::istringstream strm( buffer );
unsigned long holder = 1;
strm >> std::hex >> holder;
if( strm.fail() )
// out-of-range
if( ! strm.eof() )
// didn't read all available characters - catches "A!!!"