bagaimana cara mengubah dari int ke char *?

98

Satu-satunya cara yang saya tahu adalah:

#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();
}

Tetapi apakah ada metode lain dengan lebih sedikit mengetik?

rsk82
sumber
8
mengapa Anda menginginkan string C, bukan string C ++?
KillianDS
1
gunakan sprintf
Kasma

Jawaban:

128
  • Di C ++ 17, gunakan std::to_charssebagai:

    std::array<char, 10> str;
    std::to_chars(str.data(), str.data() + str.size(), 42);
  • Di C ++ 11, gunakan std::to_stringsebagai:

    std::string s = std::to_string(number);
    char const *pchar = s.c_str();  //use char const* as target type
  • Dan di C ++ 03, apa yang Anda lakukan baik-baik saja, kecuali digunakan constsebagai:

    char const* pchar = temp_str.c_str(); //dont use cast
Nawaz
sumber
1
Bagian pertama tidak benar-benar menjawab pertanyaan (meskipun ini adalah informasi yang berguna karena saya tidak mengetahui fungsi itu)
jcoder
1
Lebih baik :) Lebih baik saya membaca lebih lanjut tentang c ++ 11 lagi. Saya tahu tentang fitur-fiturnya yang besar tetapi ini membuat saya menyadari bahwa mungkin ada lebih banyak fitur kecil yang saya lewatkan.
jcoder
1
@ Adambean: Mengapa "tidak boleh melibatkan std :: string"? . Seseorang harus menggunakan std::stringsecara default, bukan char*.
Nawaz
1
std :: string tidak selalu tersedia, terutama untuk proyek lama. Banyak game C ++ juga masih menjauh dari std :: string. Beralih dari int ke std :: string ke char * tidak sama dengan int ke char *.
Adambean
1
@ Adambean: Jika C ++, maka saya akan menganggap std::stringtersedia secara default, kecuali secara eksplisit ditentukan dalam pertanyaan itu sendiri. Masuk akal? Juga, karena pertanyaan itu sendiri menggunakan std::string(dan std::stringstream), maka Anda tidak punya banyak alasan untuk tidak setuju dengannya.
Nawaz
11

Saya pikir Anda bisa menggunakan sprintf:

int number = 33;
char* numberstring[(((sizeof number) * CHAR_BIT) + 2)/3 + 2];
sprintf(numberstring, "%d", number);
Pierre Pellegrino Milza
sumber
1
Anda harus mengubah char * menjadi char, sekarang numberstring adalah array pointer
josefx
1
Selain itu, Anda memerlukan 12 karakter untuk mengonversi bilangan bulat 32-bit menjadi representasi basis-10 yang diakhiri nul. 10 tidak cukup untuk -2147483647.
Steve Jessop
11
Bagaimana dengan penjelasannya? (((sizeof number) * CHAR_BIT) + 2)/3 + 2tampak seperti sihir ...
Mike S
7

Anda bisa menggunakan boost

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

Solusi C-style bisa digunakan itoa, tetapi cara yang lebih baik adalah mencetak nomor ini menjadi string dengan menggunakan sprintf/snprintf . Periksa pertanyaan ini: Bagaimana cara mengubah integer menjadi string secara portabel?

Perhatikan bahwa itoafungsi tidak ditentukan di ANSI-C dan bukan bagian dari C ++, tetapi didukung oleh beberapa kompiler. Ini adalah fungsi non-standar, jadi Anda harus menghindari penggunaannya. Periksa pertanyaan ini juga: Alternatif untuk itoa () untuk mengonversi integer ke string C ++?

Perhatikan juga bahwa menulis kode gaya-C saat memprogram dalam C ++ dianggap praktik yang buruk dan terkadang disebut sebagai "gaya yang mengerikan". Anda yakin ingin mengubahnya menjadi char*string C-style ? :)

LihO
sumber
5

Saya tidak akan mengetikkan const di baris terakhir karena ada karena suatu alasan. Jika Anda tidak dapat hidup dengan const char * maka Anda lebih baik menyalin array char seperti:

char* char_type = new char[temp_str.length()];
strcpy(char_type, temp_str.c_str());
pengguna331471
sumber
maksudmu const char* char_type = temp_str.c_str();lebih baik?
rsk82
1
Iya. c_str memberi Anda penunjuk ke buffer internal objek string. Jika Anda membuang konstanta, Anda atau pemrogram lain mungkin berpikir tidak masalah untuk mengubah buffer melalui variabel non-konst. Tapi ternyata tidak. Objek string asli tidak tahu apa-apa tentang perubahan ini. Di sisi lain string masih memiliki buffer. Jika objek string keluar dari ruang lingkup memori di belakang pointer dihapus oleh destruktor objek string meninggalkan Anda dengan pointer yang menggantung. Operasi penyalinan menghilangkan kedua masalah tersebut.
pengguna331471
1
Atau std::vector<char> temp_vec(temp_str.begin(), temp_str.end()); temp_vec.push_back(0); char *char_type = &vec[0];,. Ini memberi Anda memori yang bisa berubah, meskipun tentu saja Anda masih perlu menjaga vektor tetap hidup selama Anda ingin menggunakan penunjuk.
Steve Jessop
1
Atau gunakan saja stringdan jangan repot-repot dengan yang lama, polos, bodoh char *dari yang lama, biasa C. <potongan api yang dimaksudkan>
Griwes
@Griwes: pertanyaannya adalah bagaimana caranya char*, bukan "apakah ada gunanya memanggil dari C ++ ke pustaka yang ada yang ditulis dalam C, atau haruskah saya mengimplementasikannya kembali dalam C ++?" ;-p
Steve Jessop
2

Baiklah .. pertama-tama saya membutuhkan sesuatu yang melakukan apa yang ditanyakan oleh pertanyaan ini, tetapi saya membutuhkannya CEPAT! Sayangnya cara yang "lebih baik" adalah hampir 600 baris kode !!! Maafkan namanya yang tidak ada hubungannya dengan apa yang dilakukannya. Nama yang tepat adalah Integer64ToCharArray (nilai int64_t);

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

Jangan ragu untuk mencoba membersihkan kode itu tanpa mengganggu kinerja.

Input: Nilai 64 bit apa pun yang ditandatangani dari kisaran minimum hingga maksimum.

Contoh:

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

Keluaran:

Test: 9223372036854775807
Test: -9223372036854775808

Tes Kecepatan Asli: ( Integer64ToCharArray (); )

Nilai kasus 1 digit terbaik.

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

Kasus Lebih Buruk Nilai 20 Digit.

Loop: 100.000.000, Waktu yang Dihabiskan: 22.656 (Mili), Waktu Per Loop 226 (Nano

Tes Kecepatan Desain Baru: ( AddDynamicallyToBuffer (); )

Nilai kasus 1 digit terbaik.

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

Kasus Terburuk 32 Bit - Nilai 11 digit.

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

Kasus Terburuk 1 Triliun Negatif - Nilai 14 digit.

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

Kasus 64 Bit Lebih Buruk - Nilai 20 Digit.

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

Bagaimana itu bekerja!

Kami Melakukan teknik Divide and Conquer dan setelah kami sekarang menjadi panjang maksimum string, kami cukup mengatur setiap nilai karakter secara individual. Seperti yang ditunjukkan dalam tes kecepatan di atas, panjang yang lebih besar mendapatkan penalti kinerja yang besar, tetapi masih jauh lebih cepat daripada metode loop asli dan tidak ada kode yang benar-benar berubah antara dua metode selain perulangan tidak lagi digunakan.

Dalam penggunaan saya maka nama saya mengembalikan offset sebagai gantinya dan saya tidak mengedit buffer array char, melainkan saya mulai memperbarui data vertex dan fungsi memiliki parameter tambahan untuk offset sehingga tidak diinisialisasi ke -1.

Jeremy Trifilo
sumber
0

Anda juga dapat menggunakan transmisi.

contoh:

string s;
int value = 3;
s.push_back((char)('0' + value));
elmaystro
sumber
1
Bagaimana jika nilainya negatif atau bukan digit?
Ziya ERKOC