【问题标题】:How do I convert a char array to integer/double/long type? [duplicate]如何将 char 数组转换为 integer/double/long 类型? [复制]
【发布时间】:2012-01-12 15:59:26
【问题描述】:

可能重复:
How to convert a number to string and vice versa in C++

如何将 char 数组转换为 integer/double/long 类型的 -atol() 函数?

【问题讨论】:

  • 你的意思是 minus atol 函数吗?比如,不使用它们?
  • “转换”是什么意思?是否要解析存储在字符串中的字符串数字表示?你想在你的整数中表示字符数字代码吗?

标签: c++


【解决方案1】:

使用C++ Streams

std::string hello("123"); 
std::stringstream str(hello); 
int x;  
str >> x;  
if (!str) 
{      
   // The conversion failed.      
} 

【讨论】:

    【解决方案2】:

    Boost.LexicalCast:

    boost::lexical_cast<int>("42");
    

    (C++11):

    std::stoi("42");
    

    另外,除非它是互操作的,否则不要使用 char 数组。请改用std::string。也永远不要使用 ato* 函数,即使在 C 语言中,它们也会按照设计被破坏,因为它们不能正确地发出错误信号。

    【讨论】:

    • +1 用于在 SO 上介绍 std::stoi。我以前没见过这个。
    【解决方案3】:

    你的意思是如何将它们转换为整数?您不能将字符数组转换为语言级别的函数 - 也许您可以使用某些编译器特定的内联汇编语法。要转换为整数,您可以使用atoi

    int i = atoi("123");`
    

    strtol

    long l = strtol("123", NULL, 10);
    

    【讨论】:

      【解决方案4】:
      template<class In, class Out>
      static Out lexical_cast(const In& inputValue)
              {
          Out result;
      
          std::stringstream stream(std::stringstream::in | std::stringstream::out);
          stream << inputValue;
          stream >> result;
          if (stream.fail() || !stream.eof()) {
              throw bad_cast("Cast failed");
          }
      
          return result;
      }
      

      使用它:

      int val = lexical_cast< std::string, int >( "123" );
      

      【讨论】:

      • 我可以制作一个无效的输入,使这个函数崩溃。所以我猜你的版本有安全漏洞,就像@FredOverflow 的一样?
      • @jalf Xmm 告诉我,我会修复它:)。
      • 显然,没有 bad_cast 构造函数采用 C 字符串。
      • 抱歉 bad_cast 是我的库中的一个例外,您不能按原样使用此代码。这只是一个例子。如果你愿意,你可以抛出你的异常。
      • 例如,将std::string(" 123") 传递给此函数将起作用,但传递std::string("123 ")std::string(" 123 ") 将使其抛出。不是很健壮,恕我直言。
      【解决方案5】:

      自己编写这样的函数是一个很好的练习:

      unsigned parse_int(const char * p)
      {
          unsigned result = 0;
          unsigned digit;
          while ((digit = *p++ - '0') < 10)
          {
              result = result * 10 + digit;
          }    
          return result;
      }
      

      当然,您应该更喜欢现实世界代码中现有的库设施。

      【讨论】:

      • @AlexTheodoridis:“不可移植”与“许多安全漏洞”不同。如果函数以 NULL 作为参数调用,它将立即崩溃。这是安全漏洞吗?
      • @Alex: 1) 所以?有许多 C 库函数在传递 NULL 指针时会调用未定义的行为,例如 strlen。我不会称其为安全漏洞。 2)我正在做无符号比较。 (digit = *p++ - '0') 将为低于 '0' 的字符生成大于 10 的值。 3) 每个现实世界的字符编码都有连续的数字,甚至是 EBCDIC。
      • @Alex:我的函数究竟何时会产生“意外输出”?请提供示例输入字符串、预期输出和实际(错误)输出。
      • 我在这里,无法对 cme​​ts 投反对票... :P @Alex:如果您可以提供此代码的示例,该代码可以执行除设计目的之外的任何操作,请随时分享。否则,请停止讨论“安全漏洞”。这里发生的最多的是他假设这个函数的用户不是白痴,并且已经将一个非空指针传递给一个以空结尾的字符串。就像,你知道的,&lt;string.h&gt; 中的几乎每个函数都假设。
      • @Alex C++ 标准保证数字是连续的。所以不,x - '0' 依赖于 ASCII 表,它只依赖于 C++ 标准,我认为这是可以接受的。 (参考:第 2.3p4 节“在源和执行基本字符集中,上述十进制数字列表中 0 之后的每个字符的值应比前一个值大一。”)
      猜你喜欢
      • 2016-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-19
      • 1970-01-01
      • 2017-05-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多