如何从字符串中获取 unsigned long ?

发布于 2024-08-06 03:38:07 字数 936 浏览 10 评论 0原文

在 C++ 中从字符串中检索 unsigned long 的最安全、最好的方法是什么?

我知道有很多可能的方法。

首先,转换从 atol 获取的有符号长整数。

char *myStr; // Initalized to some value somehow.
unsigned long n = ((unsigned)atol(myStr));

明显的问题是,当 myStr 中存储的值大于有符号 long 可以包含的值时会发生什么? atol 检索什么?

下一个可能性是使用 strtoul。

char *myStr; // Initalized to some value somehow.
unsigned long n = strtoul(myStr, 0, 10);

然而,这对于我的需求来说有点过于复杂。我想要一个简单的函数,字符串输入,无符号长基数 10 输出。此外,错误处理还有很多不足之处。

我发现的最后一种可能性是使用 sscanf。

char *myStr; // Initalized to some value somehow.
unsigned long n = 0;
if(sscanf(myStr, "%lu", n) != 1) {
    //do some error handling
}

同样,错误处理还有很多不足之处,而且比我想要的要复杂一些。

剩下的明显选项是编写我自己的包装器,围绕先前的可能性之一,或者循环遍历字符串并手动转换每个数字,直到达到 ULONG_MAX。

我的问题是,我的 google-fu 找不到的其他选项是什么? C++ std 库中是否有任何东西可以将字符串干净地转换为无符号长整型并在失败时抛出异常?

如果这是一个骗局,我很抱歉,但我找不到任何与我的问题完全匹配的问题。

What's the safest and best way to retrieve an unsigned long from a string in C++?

I know of a number of possible methods.

First, converting a signed long taken from atol.

char *myStr; // Initalized to some value somehow.
unsigned long n = ((unsigned)atol(myStr));

The obvious problem with this is, what happens when the value stored in myStr is larger than a signed long can contain? What does atol retrieve?

The next possibility is to use strtoul.

char *myStr; // Initalized to some value somehow.
unsigned long n = strtoul(myStr, 0, 10);

However, this is a little over complicated for my needs. I'd like a simple function, string in, unsigned long base 10 out. Also, the error handling leaves much to be desired.

The final possibility I have found is to use sscanf.

char *myStr; // Initalized to some value somehow.
unsigned long n = 0;
if(sscanf(myStr, "%lu", n) != 1) {
    //do some error handling
}

Again, error handling leaves much to be desired, and a little more complicated than I'd like.

The remaining obvious option is to write my own either a wrapper around one of the previous possibilities or some thing which cycles through the string and manually converts each digit until it reaches ULONG_MAX.

My question is, what are the other options that my google-fu has failed to find? Any thing in the C++ std library that will cleanly convert a string to an unsigned long and throw exceptions on failure?

My apologies if this is a dupe, but I couldn't find any questions that exactly matched mine.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

心的憧憬 2024-08-13 03:38:07

您可以毫无问题地使用 strtoul。该函数返回一个无符号长整型。如果无法执行转换,则函数返回 0。如果正确的 long 值超出范围,则函数返回 ULONG_MAX,并将 errno 全局变量设置为 ERANGE。

You can use strtoul with no problem. The function returns an unsigned long. If convertion can not be performed the function return 0. If the correct long value is out of range the function return ULONG_MAX and the errno global variable is set to ERANGE.

风情万种。 2024-08-13 03:38:07

一种方法是:

stringstream(str) >> ulongVariable;

One way to do it:

stringstream(str) >> ulongVariable;
话少心凉 2024-08-13 03:38:07
template <class T>
T strToNum(const std::string &inputString,
           std::ios_base &(*f)(std::ios_base&) = std::dec)
{
    T t;
    std::istringstream stringStream(inputString);

    if ((stringStream >> f >> t).fail())
    {
        throw runtime_error("Invalid conversion");
    }
    return t;
}


// Example usage
unsigned long ulongValue = strToNum<unsigned long>(strValue);
int intValue             = strToNum<int>(strValue);

int intValueFromHex      = strToNum<int>(strHexValue,std::hex);
unsigned long ulOctValue = strToNum<unsigned long>(strOctVal, std::oct);
template <class T>
T strToNum(const std::string &inputString,
           std::ios_base &(*f)(std::ios_base&) = std::dec)
{
    T t;
    std::istringstream stringStream(inputString);

    if ((stringStream >> f >> t).fail())
    {
        throw runtime_error("Invalid conversion");
    }
    return t;
}


// Example usage
unsigned long ulongValue = strToNum<unsigned long>(strValue);
int intValue             = strToNum<int>(strValue);

int intValueFromHex      = strToNum<int>(strHexValue,std::hex);
unsigned long ulOctValue = strToNum<unsigned long>(strOctVal, std::oct);
七颜 2024-08-13 03:38:07

如果您可以使用 boost 库(www.boost.org)查看转换库 - 它只是一个标头,

#include "boost/lexical_cast.hpp"

那么您需要做的就是

unsigned long ul = boost::lexical_cast<unsigned long>(str);

If you can use the boost libraries (www.boost.org) look at the conversion library - it's a header only include

#include "boost/lexical_cast.hpp"

then all you need to do is

unsigned long ul = boost::lexical_cast<unsigned long>(str);
拥抱影子 2024-08-13 03:38:07

Jeffrey Stedfast 有一篇精彩的文章,介绍了为 Mono 编写 int 解析器例程 (在C)中。
它生成使用本机类型的代码(您需要 32 位来解析 32 位)和溢出错误代码。

Jeffrey Stedfast has a beautiful post about writing int parser routines for Mono (in C).
It generates code that uses uses native types (you need 32 bit to parse 32 bit) and error codes for overflow.

蓝戈者 2024-08-13 03:38:07

使用“atol”内置 std 函数

例如 std::string input = "1024";

std::atol(input.c_str());

Atol 期望参数为 c 字符串类型,因此 c_str() 会为您完成此操作。

Use "atol" in-built std function

For example std::string input = "1024";

std::atol(input.c_str());

Atol expect parameter to be of type c string, so c_str() does it that for you.

此生挚爱伱 2024-08-13 03:38:07

稳健的方式将是
编写一个静态函数并使用它

bool str2Ulong(const string& str,unsigned long & arValue)
{
   char *tempptr=NULL;
   arValue=strtoul(str,tempptr,10);

   return ! (arValue==0 && tempptr==str.c_str());

}

Robust way will be
write a static function and use it

bool str2Ulong(const string& str,unsigned long & arValue)
{
   char *tempptr=NULL;
   arValue=strtoul(str,tempptr,10);

   return ! (arValue==0 && tempptr==str.c_str());

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文