【问题标题】:How to convert from const char* to unsigned int c++如何从 const char* 转换为 unsigned int c++
【发布时间】:2010-10-26 14:38:50
【问题描述】:

我是 C++ 编程的新手,我一直在尝试从 const char* 转换为 unsigned int,但没有成功。 我有一个:

const char* charVar;

我需要将其转换为:

unsigned int uintVar;

如何在 C++ 中完成?

谢谢

【问题讨论】:

  • -1 不清楚您在此处使用 convert 是什么意思。你尝试了什么?

标签: c++


【解决方案1】:
#include <iostream>
#include <sstream>

const char* value = "1234567";
stringstream strValue;
strValue << value;

unsigned int intValue;
strValue >> intValue;

cout << value << endl;
cout << intValue << endl;

输出:

1234567

1234567

【讨论】:

  • 很好的例子。我将 unsigned int 更改为 just int,现在它似乎也可以处理负数。
  • 这个答案不涉及强制转换,它带来了一堆 C++ 不一定需要的复杂特性。理想情况下,您会弄清楚如何根本不使用 stl 或模板。引入这些功能会大大增加编译时间。当我摆脱对 stl 的大多数引用的小型 xml 解析器时,编译时间从 30 秒缩短到不到 1 秒。这就是为什么大型项目最终需要花费一个小时来编译的原因,除非你家里有 64 核 cpu。
【解决方案2】:

转换是什么意思?

如果您正在谈论从文本中读取整数,那么您有多种选择。

提升词法转换:http://www.boost.org/doc/libs/1_44_0/libs/conversion/lexical_cast.htm

字符串流:

const char* x = "10";
int y;
stringstream s(x);
s >> y;

或者不错的旧 C 函数 atoi()strtol()

【讨论】:

  • ...虽然我现在很想删除它以迎合 CRT :-)
【解决方案3】:

如果您真的想将指向常量字符的指针转换为无符号整数,那么您应该在 c++ 中使用:

const char* p;
unsigned int i = reinterpret_cast<unsigned int>( p );

这会将指针指向的地址转换为无符号整数。

如果要将指针指向的内容转换为无符号整数,应使用:

const char* p;
unsigned int i = static_cast<unsigned int>( *p );

如果您想从字符串中获取整数,从而将 const char* 解释为指向 const char 数组的指针,则可以使用上述解决方案之一。

【讨论】:

    【解决方案4】:

    C 方式:

    #include <stdlib.h>
    int main() {
        const char *charVar = "16";
        unsigned int uintVar = 0;
    
        uintVar = atoi(charVar);
    
        return 0;
    }
    

    C++ 方式:

    #include <sstream>
    int main() {
        istringstream myStream("16");
        unsigned int uintVar = 0;
    
        myStream >> uintVar;
    
        return 0;
    }
    

    请注意,在这两种情况下,我都没有检查转换的返回码以确保它确实有效。

    【讨论】:

      【解决方案5】:

      在 C 中,这可以使用 atoi 完成,C++ 也可以通过 cstdlib 使用。

      【讨论】:

      • atoi("blah") 返回什么?这与atoi(0) 有何不同?
      • 请注意,atoi() 可能是所有可用选项中最糟糕的选择。
      • 它被称为 C 运行时库是有原因的。
      • atoi 是否不好取决于您的用例。首先,它是迄今为止所有解决方案中最短的。另一方面,它不进行错误检查。所以这真的只是我经常发现有用的一种快速而肮脏的方法。
      • 我还没有找到一个用例,我不介意我是否在没有任何实际迹象的情况下得到了错误的数据。
      【解决方案6】:

      我通常使用这个通用函数将字符串转换为“任何东西”:

        #include <sstream>
        // Convert string values into type T results.
        // Returns false in case the conversion fails.
        template <typename T>
        bool getValueFromString( const std::string & value, T & result )
        {
          std::istringstream iss( value );
          return !( iss >> result ).fail();
        }
      

      只需像这样使用它:

      int main()
      {
        const char * a_string = "44";
        unsigned int an_int;
        bool         success;
      
        // convert from const char * into unsigned int
        success = getValueFromString( a_string, an_int );
      
      
        // or any other generic convertion
        double       a;
        int          b;
        float        c;
        // conver to into double
        success = getValueFromString( "45", a );
      
        // conve rto into int
        success = getValueFromString( "46", b );
      
        // conver to into float
        success = getValueFromString( "47.8", c );
      }
      

      【讨论】:

      • “任何东西”?它不适用于负整数。即使您调用getValueFromString("-123", an_int)success 也将等于 0,并且您将在 an_int 中获得垃圾值。
      • @glihm: an_int 被声明为unsigned int,因此您不能为其分配负数。并且存储在 an_int 中的不是“垃圾”,而是 -123 的 2 的补码表示。
      • 哦,太好了@Sdra,感谢澄清!我试过了,虽然这些价值观是垃圾。 :)
      【解决方案7】:

      atoi 函数会将 const char* 转换为 int,可以隐式转换为 unsigned。这不适用于不适合 int 的大整数。

      更 C++ 的方式是使用字符串和流

      #include <sstream>
      #include <string>
      
      int main()
      {
         std::string strVar;
         unsigned uintVar;
         std::istringstream in(strVar);
         in >> uintVar;
      }
      

      一种更简单但非标准的方法是使用 boost 的 lexical cast

      HTH

      【讨论】:

      • 这样的答案的问题是他们需要学习 C 方法以提高性能。他们必须了解 stringstream 如何在后台工作,并在使用默认值之前构建自己的。至少,我认为应该教 C++ 的方式是你教 C,然后让他们为课堂构建基本的 C++。
      • @ZeroPhase:作为一个教 C++ 大约 10 年的人,我的看法完全相反。在我看来,尝试“自下而上”学习 C++ 是不行的。
      【解决方案8】:

      所以我知道这已经过时了,但我想我会提供一种更有效的方法来做这件事,这将使你在你想要的基础上有一些灵活性。

      #include<iostream>
      
      unsigned long cstring_to_ul(const char* str, char** end = nullptr, int base = 10)
      {
          errno = 0; // Used to see if there was success or failure
      
          auto ul = strtoul(str, end, base);
      
          if(errno != ERANGE)
          {
             return ul;
          }
      
          return ULONG_MAX;
      }
      

      这将做的是围绕 C 中的 strtoul(const char* nptr, char** endptr, int base) 方法创建一个包装器。有关此函数的更多信息,您可以在此处阅读手册页中的描述@ 987654321@

      如果失败,您将获得 errno = ERANGE,这将允许您在调用此函数后进行检查,并且值为 ULONG_MAX。

      使用它的示例如下:

      int main()
      {
          unsigned long ul = cstring_to_ul("3284201");
      
          if(errno == ERANGE && ul == ULONG_MAX)
          {
              std::cout << "Input out of range of unsigned long.\n";
              exit(EXIT_FAILURE);
          }
      
          std::cout << "Output: " << ul << "\n";
       }
      

      这将给出输出

      输出:3284201

      【讨论】:

        【解决方案9】:

        如果没有更多信息,就无法正确回答这个问题。你想确切地转换什么?如果 charVar 是字符串的 ascii 表示,那么您可以像其他人建议的那样使用 stringstreams、atoi、sscanf 等。

        如果你想要 charVar 所指向的实际值,那么你会想要类似的东西:

        intValue = (unsigned int)(*charVal);
        

        或者如果 charVal 是指向无符号整数第一个字节的指针,则:

        intValue = *((unsigned int*)(charVal));

        【讨论】:

        • 这不会违反严格的别名规则吗?
        • Let_Me_Be:我一直认为转换为 char* 或从 char* 转换是有效的。我调查了一下,实际上它似乎只对 char* 有效,但对 char* 无效。我经常看到这个成语,所以我需要做一些额外的研究。
        【解决方案10】:
        const char* charVar = "12345";
        unsigned int uintVar;
        try {
          uintVar = std::stoi( std::string(charVar) );
        }
        catch(const std::invalid_argument& e) {
          std::cout << "Invalid Arg: " << e.what() << endl;
        }
        catch(const std::out_of_range& e) {
          std::cout << "Out of range: " << e.what() << endl;
        }
        

        【讨论】:

          【解决方案11】:

          您也可以使用strtoul_tcstoulconst char* 获取无符号长整型值,然后将该值转换为无符号整数。

          http://msdn.microsoft.com/en-us/library/5k9xb7x1(v=vs.71).aspx

          【讨论】:

            【解决方案12】:
            const char* charVar = "1864056953";
            unsigned int uintVar = 0;
            
            for (const char* it = charVar; *it != 0; *it++){
            
                if ((*it < 48) || (*it > 57)) break;            // see ASCII table
            
                uintVar *= 10;                                  // overflow may occur
                uintVar += *it - 48;                            // 
            }
            
            std::cout << uintVar << std::endl;
            std::cout << charVar << std::endl;
            

            【讨论】:

            • 如果你使用'0'而不是48'9'而不是57你就不会依赖ASCII。
            • 另外,在*it++* 无效。 it++ 就足够了(我实际上会使用++it)。最后,uintVar &lt; 0 比较没有意义,因为您的数据类型是 unsigned
            • 我的回答是试图展示一些概念性的观点。否则,2 行解决方案将是这里的最佳选择。
            • it++ 是不够的。 (感谢 unsigned int)
            • *it++ 没有意义。你增加指针然后你取消引用它,但你没有对你得到的值做任何事情。
            【解决方案13】:

            这样试试

            #include<iostream>
            #include <typeinfo>             //includes typeid
            
            using namespace std;
            
            int main(){
            
            char a  = '3';
            int k = 3;
            
            const char* ptr = &a;
            
            cout << typeid(*ptr).name() << endl;                    //prints the data type c = char
            cout << typeid(*ptr-'0').name() << endl;                //prints the data type i = integer
            
            cout << *ptr-'0' << endl;
            
            return 0;
            }
            

            【讨论】:

            • 虽然此代码可以解决问题,including an explanation 说明如何以及为什么解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请edit您的答案以添加解释并说明适用的限制和假设。 From Review
            猜你喜欢
            • 1970-01-01
            • 2010-10-14
            • 2012-04-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-10-16
            • 1970-01-01
            相关资源
            最近更新 更多