how to convert from int to char*?

2019-01-08 05:29发布

问题:

The only way I know is:

#include <sstream>
#include <string.h>
using namespace std;

int main() {
  int number=33;
  stringstream strs;
  strs << number;
  string temp_str = strs.str();
  char* char_type = (char*) temp_str.c_str();
}

But is there any method with less typing ?

回答1:

  • In C++17, use std::to_chars as:

    std::array<char, 10> str;
    std::to_chars(str.data(), str.data() + str.size(), 42);
    
  • In C++11, use std::to_string as:

    std::string s = std::to_string(number);
    char const *pchar = s.c_str();  //use char const* as target type
    
  • And in C++03, what you're doing is just fine, except use const as:

    char const* pchar = temp_str.c_str(); //dont use cast
    


回答2:

You can use boost

#include <boost/lexical_cast.hpp>
string s = boost::lexical_cast<string>( number );


回答3:

I think you can use a sprintf :

int number = 33;
char* numberstring[(((sizeof number) * CHAR_BIT) + 2)/3 + 2];
sprintf(numberstring, "%d", number);


回答4:

C-style solution could be to use itoa, but better way is to print this number into string by using sprintf / snprintf. Check this question: How to convert an integer to a string portably?

Note that itoa function is not defined in ANSI-C and is not part of C++, but is supported by some compilers. It's a non-standard function, thus you should avoid using it. Check this question too: Alternative to itoa() for converting integer to string C++?

Also note that writing C-style code while programming in C++ is considered bad practice and sometimes referred as "ghastly style". Do you really want to convert it into C-style char* string? :)



回答5:

I would not typecast away the const in the last line since it is there for a reason. If you can't live with a const char* then you better copy the char array like:

char* char_type = new char[temp_str.length()];
strcpy(char_type, temp_str.c_str());


回答6:

See this answer https://stackoverflow.com/a/23010605/2760919

For your case, just change the type in snprintf from long ("%ld") to int ("%n").



回答7:

You also can use casting.

example:

string s;
int value = 3;
s.push_back((char)('0' + value));


回答8:

This might be a bit late, but i also had the same issue. Converting to char was addressed in C++17 with the "charconv" library.

https://en.cppreference.com/w/cpp/utility/to_chars



回答9:

Alright my way isn't exactly "less code" like you wanted, but I found the recommended ways to be way too slow for my usage.

Usage is simple:

Integer64ToCharArray(-1); //Replace -1 with your number.

This supports all numbers between 64bit MIN and MAX VALUES.

Something to keep in mind... I made the returned buffer static in the method. I set it to a size of 21 to ensure 21 bytes is allocated. Which is the maximum size a digits and negative and length index of LONG value can be. So this is safe to execute as many times as you'd like where as many other ways allocate new memory ever time they are called.

I needed something that would allow me to convert Integers to char arrays quickly so I could convert them into quads for font rendering. All the above methods are just far too slow for my needs. This should be able get the char value of 2500 numbers with up to 19 digits in under 1ms.

char *Integer64ToCharArray(int64_t num)
{
    uint64_t value = num;
    int neg = num < 0;
    if (neg)
        value = -num;
    int len = 0;
    if (value >= 1000000000) //10 Digit.
    {
        if (value >= 100000000000000) //15 Digit.
        {
            if (value >= 10000000000000000) //17 Digits.
            {       
                if (value >= 1000000000000000000)
                    len = 19;
                else
                {
                    if (value >= 100000000000000000)
                        len = 18;
                    else
                        len = 17;
                }
            }
            else
            {
                if (value >= 1000000000000000)
                    len = 16;
                else
                {
                    len = 15;
                }
            }
        }
        else {
            if (value >= 100000000000) // 12 Digits.
            {
                if (value >= 10000000000000) //14 Digits.
                    len = 14;
                else
                {
                    if (value >= 1000000000000) //13 Digits.
                        len = 13;
                    else
                        len = 12; //12 Digits.
                }
            }
            else
            {
                if (value >= 10000000000)
                    len = 11; //11 Digits.
                else
                {
                    len = 10; //10 Digits.
                }
            }
        }
    }
    else {
        if (value >= 100000) //6 Digit.
        {
            if (value >= 10000000)
            {
                if (value >= 100000000)
                    len = 9;
                else
                    len = 8;
            } 
            else
            {
                if (value >= 1000000)
                    len = 7;
                else
                    len = 6;
            }
        }
        else {
            if (value >= 1000)
            {
                if (value >= 10000)
                    len = 5;
                else
                    len = 4;
            }
            else
            {
                if (value >= 100)
                    len = 3;
                else
                {
                    if (value >= 10)
                        len = 2;
                    else
                        len = 1;
                }
            }
        }
    }

    static const uint64_t REDUCTION[20] =
    {
        1,
        1,
        10,
        100,
        1000,
        10000,
        100000,
        1000000,
        10000000, //8
        100000000,
        1000000000,
        10000000000,
        100000000000,
        1000000000000,
        10000000000000,
        100000000000000,
        1000000000000000,
        10000000000000000, //17
        100000000000000000, //18
        1000000000000000000, //19
    };

    static buffer[21];
    //switch to this if you want unique copies. remember to delete though.
    //char* buffer = new char[len + neg + 1];

    if (neg)
        buffer[0] = '-';

    buffer[len + neg] = '\0';

    uint64_t reduction = REDUCTION[len];

    for (int j = -1; ++j < len; )
    {
        int c_value = (value / reduction);
        buffer[j + neg] = 48 + c_value;
        value -= reduction * c_value;
        reduction *= 0.1;
    }

    return buffer;
}

!!SPEED TESTS!!

Your Answer

Loops: 500,000, Time Spent: 5,428(Milli), Time Per Loop 10,856(Nano)

My Way Of Doing It

Best case 1 digit value.

Loops: 10,000,000, Time Spent: 493(Milli), Time Per Loop 49(Nano)

Worse Case 19 Digit Value.

Loops: 10,000,000, Time Spent: 2,192(Milli), Time Per Loop 219(Nano)

SprintF Way As Mentioned In Comments

Well doing sprintf_s was damn near the same.

char* SPrintStyle(int64_t num)
{
    static char number_string[21];
    int length = sprintf_s(number_string, "%lld", num);
    return number_string;
}

Worse Case: Loops: 10000000, Time Spent: 3102(Milli), Time Per Loop 310(Nano)

Best Case: Loops: 10000000, Time Spent: 1189(Milli), Time Per Loop 118(Nano)