127

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 ?

rsk82
  • 28,217
  • 50
  • 150
  • 240

10 Answers10

170
  • 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
    
Cinder Biscuits
  • 4,880
  • 31
  • 51
Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • 1
    The first part doesn't actually answer the question (although it is good helpful information as I wasn't aware of that function) – jcoder Jun 01 '12 at 09:31
  • 1
    Better :) Plus I better go read more about c++11 again. I know about the big features but this has made me realize there are probably more small ones I missed. – jcoder Jun 01 '12 at 10:33
  • This doesn't answer the question. int to char* should not involve std::string. – Adambean Jan 24 '16 at 18:55
  • 1
    @Adambean: Why it "should not involve std::string"? . One should use `std::string` by default, instead of `char*`. – Nawaz Jan 25 '16 at 10:49
  • 1
    std::string isn't always available, particularly to older projects. Plenty of C++ games also still stay away from std::string. Going from int to std::string to char* isn't the same as int to char*. – Adambean Jan 25 '16 at 19:05
  • 1
    @Adambean: If it is C++, then I'm going to assume `std::string` is available by default, unless it is explicitly specified in the question itself. Makes sense? Also, since the question itself uses `std::string` (and `std::stringstream`), then you dont have much reason to disagree with it. – Nawaz Jan 26 '16 at 07:03
  • 1
    Using c_str is bad. When the string it is pointing to becomes out of scope, it gives irrelevent values – Amin Guermazi May 04 '20 at 13:47
  • @Nawaz Is there any potencial problem for `char const* pchar = temp_str.c_str()` since `temp_str` is temporary? Is it the memory is availble when the string is destroied? – John Sep 27 '21 at 03:04
  • @John: Nope. `temp_str` owns the memory. So when it's destroyed, `pchar` would point to invalid memory. In this sense, there is a problem. One needs to use such code carefully. – Nawaz Sep 27 '21 at 11:03
14

I think you can use a sprintf :

int number = 33;
char* numberstring[(((sizeof number) * CHAR_BIT) + 2)/3 + 2];
sprintf(numberstring, "%d", number);
Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
  • 1
    you should change char* to char, right now numberstring is an array of pointers – josefx Jun 01 '12 at 09:10
  • 1
    Also, you need 12 characters to convert a 32-bit integer to a nul-terminated base-10 representation. 10 isn't enough for `-2147483647`. – Steve Jessop Jun 01 '12 at 09:12
  • 18
    How about some explanation? `(((sizeof number) * CHAR_BIT) + 2)/3 + 2` looks like wizardry... – Mike S May 24 '17 at 21:35
  • 1
    Although it works this example is creating a pointer to a pointer `char *numberString[someNumber]`. It is more simple to do: `int number = 123; char numberstring[10]; sprintf(numberstring, "%d", number); printf("the number is: %s \n", (char*)numberstring); ` – Tono Nam Nov 16 '20 at 01:36
  • @MikeS Did you figure it out ? :P I would really like to know how it works – Claudio Pisa May 10 '21 at 22:04
7

You can use boost

#include <boost/lexical_cast.hpp>
string s = boost::lexical_cast<string>( number );
maverik
  • 5,508
  • 3
  • 35
  • 55
5

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? :)

Community
  • 1
  • 1
LihO
  • 41,190
  • 11
  • 99
  • 167
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());
Widor
  • 13,003
  • 7
  • 42
  • 64
user331471
  • 873
  • 1
  • 9
  • 19
  • you mean `const char* char_type = temp_str.c_str();` is better ? – rsk82 Jun 01 '12 at 09:02
  • 1
    Yes. c_str gives you a pointer to the internal buffer of the string object. If you cast away the const you or another programmer could think it is ok to change the buffer through the non-const variable. But it is not. The original string object does not know anything about these changes. On the other hand the string still owns the buffer. If the string object goes out of scope the memory behind the pointer is deleted by the string objects destructor leaving you with a dangling pointer. The copy operation removes both problemes. – user331471 Jun 01 '12 at 09:05
  • 1
    Alternatively, `std::vector temp_vec(temp_str.begin(), temp_str.end()); temp_vec.push_back(0); char *char_type = &vec[0];`. This gives you mutable memory, although of course you still need to keep the vector alive for as long as you want to use the pointer. – Steve Jessop Jun 01 '12 at 09:08
  • 1
    Or just use `string` and don't bother with old, plain, stupid `char *` from old, plain C. – Griwes Jun 01 '12 at 09:33
  • @Griwes: the question is how to get to `char*`, not "is there any point calling from C++ into existing libraries written in C, or should I re-implement them in C++?" ;-p – Steve Jessop Jun 03 '12 at 09:57
  • @SteveJessop, so if someone chooses broken solution, we should provide him answers to that broken solution, not teach them how to avoid issues arising from using broken solutions? – Griwes Jun 03 '12 at 11:25
  • @Griwes: I don't think that calling C libraries from other languages is "broken". So I think it's incorrect to say that trying to get a `char*` pointing to a string is "stupid". Of course it's possible that the questioner is making a mistake, I just don't think it's helpful to assume that and flame him or her on that basis. Even if it's only flaming "a bit". – Steve Jessop Jun 03 '12 at 14:01
  • @SteveJessop, `char *` as "string" is broken and stupid solution, as long as there are better ones - like `std::string`, which is natural way to use strings in C++. – Griwes Jun 03 '12 at 14:08
  • @Griwes: the questioner is clearly aware of `std::string`, having used it in the example code in the question. Good luck passing your `std::string` into that C library. Or whatever other use it is that the questioner has for a `char*` -- cross-language interfaces is just the most obvious example. – Steve Jessop Jun 03 '12 at 14:12
3

Alright.. firstly I needed something that did what this question is asking, but I needed it FAST! Unfortunately the "better" way is nearly 600 lines of code!!! Pardon the name of it that doesn't have anything to do with what it's doing. Proper name was Integer64ToCharArray(int64_t value);

https://github.com/JeremyDX/All-Language-Testing-Code/blob/master/C%2B%2B%20Examples/IntegerToCharArrayTesting.cpp

Feel free to try cleaning that code up without hindering performance.

Input: Any signed 64 bit value from min to max range.

Example:

std::cout << "Test: " << AddDynamicallyToBuffer(LLONG_MAX) << '\n';
std::cout << "Test: " << AddDynamicallyToBuffer(LLONG_MIN) << '\n';

Output:

Test: 9223372036854775807
Test: -9223372036854775808

Original Speed Tests: (Integer64ToCharArray();)

Best case 1 digit value.

Loops: 100,000,000, Time Spent: 1,381(Milli), Time Per Loop 13(Nano)

Worse Case 20 Digit Value.

Loops: 100,000,000, Time Spent: 22,656(Milli), Time Per Loop 226(Nano

New Design Speed Tests: (AddDynamicallyToBuffer();)

Best case 1 digit value.

Loops: 100,000,000, Time Spent: 427(Milli), Time Per Loop 4(Nano)

32 Bit Worst Case - 11 digit Value.

Loops: 100,000,000, Time Spent: 1,991(Milli), Time Per Loop 19(Nano)

Negative 1 Trillion Worst Case - 14 digit Value.

Loops: 100,000,000, Time Spent: 5,681(Milli), Time Per Loop 56(Nano)

64 Bit Worse Case - 20 Digit Value.

Loops: 100,000,000, Time Spent: 13,148(Milli), Time Per Loop 131(Nano)

How It Works!

We Perform a Divide and Conquer technique and once we now the maximum length of the string we simply set each character value individually. As shown in above speed tests the larger lengths get big performance penalties, but it's still far faster then the original loop method and no code has actually changed between the two methods other then looping is no longer in use.

In my usage hence the name I return the offset instead and I don't edit a buffer of char arrays rather I begin updating vertex data and the function has an additional parameter for offset so it's not initialized to -1.

Jeremy Trifilo
  • 456
  • 6
  • 11
2

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

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

Community
  • 1
  • 1
bonnyz
  • 13,458
  • 5
  • 46
  • 70
1

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

Cinder Biscuits
  • 4,880
  • 31
  • 51
AKJ
  • 950
  • 2
  • 13
  • 18
1

Converting our integer value to std::string so we can know how long (how long number of digits).

Then we creating char array length of string letter size +1, so we can copy our value to string then char array.

#include <string>

char* intToStr(int data) {
    std::string strData = std::to_string(data);

    char* temp = new char[strData.length() + 1];
    strcpy(temp, strData.c_str());

   return temp;
}
Emrexdy
  • 156
  • 1
  • 2
  • 8
0

You also can use casting.

example:

string s;
int value = 3;
s.push_back((char)('0' + value));
elmaystro
  • 117
  • 2
  • 7