як перетворити з int в char *?


98

Єдиний спосіб мене знає:

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

Але чи є метод із меншим типом?


8
чому ви хочете C-рядок замість рядка C ++?
— KillianDS

1
використовувати sprintf
— Касма

Відповіді:


128
  • В C ++ 17 використовуйте std::to_charsяк:

    std::array<char, 10> str;
    std::to_chars(str.data(), str.data() + str.size(), 42);
  • В C ++ 11 використовуйте std::to_stringяк:

    std::string s = std::to_string(number);
    char const *pchar = s.c_str();  //use char const* as target type
  • А в C ++ 03 те, що ви робите, це просто добре, за винятком використання constяк:

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

1
Перша частина насправді не відповідає на питання (хоча це корисна корисна інформація, оскільки я не знав про цю функцію)
— jcoder

1
Краще :) Плюс я краще перегляньте детальніше про c ++ 11 ще раз. Я знаю про великі риси, але це змусило мене зрозуміти, що, мабуть, більше малих я пропустив.
— jcoder

1
@Adambean: Чому він "не повинен включати std :: string"? . Слід використовувати std::stringза замовчуванням, а не char*.
— Наваз

1
std :: string не завжди доступний, особливо для старих проектів. Безліч C ++ ігор також залишаються подалі від std :: string. Перехід від int до std :: string to char * не те саме, що int to char *.
— Адамбій

1
@Adambean: Якщо це C ++, то я вважаю, що std::stringвін доступний за замовчуванням, якщо це прямо не зазначено в самому запитанні. Має сенс? Крім того, оскільки саме питання використовує std::string(і std::stringstream), то у вас немає великої причини з цим не погоджуватися.
— Наваз

11

Я думаю, ви можете використовувати спринт:

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

1
ви повинні змінити char * на char, зараз
— числовий рядок

1
Крім того, вам потрібно 12 символів для перетворення 32-бітного цілого числа в нульове завершення представлення базової-10. 10 недостатньо для -2147483647.
— Стів Джессоп

11
Як щодо якогось пояснення? (((sizeof number) * CHAR_BIT) + 2)/3 + 2виглядає як чарівництво ...
— Майк S

7

Ви можете використовувати прискорення

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

5

Рішенням у стилі С може бути використання itoa, але кращим способом є друк цього номера в рядку за допомогою sprintf/snprintf . Перевірте це питання: Як перетворити ціле число на рядок портативно?

Зауважте, що itoaфункція не визначена в ANSI-C і не є частиною C ++, але підтримується деякими компіляторами. Це нестандартна функція, тому вам слід уникати її використання. Перевірте також це питання: Альтернатива itoa () для перетворення цілого числа в рядок C ++?

Також зауважте, що написання коду в стилі С під час програмування на C ++ вважається поганою практикою і іноді називається "примарним стилем". Ви дійсно хочете перетворити його в char*рядок у стилі C ? :)


5

Я б не набрав const в останньому рядку, оскільки він там є чомусь. Якщо ви не можете жити з const char *, то краще скопіюйте масив char так:

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

ти маєш на увазі const char* char_type = temp_str.c_str();, що краще?
— rsk82

1
Так. c_str дає вам вказівник на внутрішній буфер об'єкта рядка. Якщо ви відкинете const, ви або інший програміст може подумати, що нормально змінити буфер через змінну non-const. Але це не так. Оригінальний об'єкт рядка нічого не знає про ці зміни. З іншого боку, рядок все ще належить буфері. Якщо об'єкт рядка виходить за межі області, пам'ять за вказівником видаляється деструктором рядкових об'єктів, залишаючи вам звисаючий покажчик. Операція копіювання усуває обидві проблеми.
— user331471

1
Як альтернативи std::vector<char> temp_vec(temp_str.begin(), temp_str.end()); temp_vec.push_back(0); char *char_type = &vec[0];. Це дає вам змінну пам’ять, хоча, звичайно, вам все одно потрібно підтримувати вектор живим, поки ви хочете використовувати вказівник.
— Стів Джессоп

1
Або просто користуйтеся stringі не турбуйтеся зі старим, простим, дурним char *від старого, простого C. <шматочки полум'я призначені>
— Griwes

@Griwes: питання полягає в тому, як дістатися char*, чи не "чи є якийсь виклик з C ++ в існуючі бібліотеки, написані на C, або я повинен повторно реалізувати їх у C ++?" ;-p
— Стів Джессоп

2

Добре .. по-перше, мені було потрібно щось, що робило те, що задається цим питанням, але мені це було потрібно Швидше! На жаль, "кращий" спосіб - це майже 600 рядків коду !!! Вибачте його, яке не має нічого спільного з тим, що він робить. Власне ім’я було Integer64ToCharArray (значення int64_t);

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

Спробуйте спробувати очистити цей код, не заважаючи виконувати його.

Введення: Будь-яке підписане 64-бітове значення від мінімуму до максимального діапазону.

Приклад:

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

Вихід:

Test: 9223372036854775807
Test: -9223372036854775808

Оригінальні тести швидкості: ( Integer64ToCharArray (); )

Найкраще значення з 1 цифрою.

Петлі: 100 000 000, Час витрати: 1,381 (Міллі), Час за цикл 13 (Нано)

Гірший випадок значення 20 цифр.

Петлі: 100 000 000, Час витрачання: 22 656 (Міллі), Час за цикл 226 (Нано

Нові тести на швидкість дизайну: ( AddDynamicallyToBuffer (); )

Найкраще значення з 1 цифрою.

Петлі: 100 000 000, Час витрати: 427 (Міллі), Час за цикл 4 (Нано)

32 біт найгірший випадок - значення 11 знаків.

Петлі: 100 000 000, Час витрати: 1,991 (Міллі), Час за цикл 19 (Нано)

Від’ємний найгірший випадок на 1 трлн. - значення у 14 цифрах.

Петлі: 100 000 000, Час витрачання: 5,681 (Міллі), Час за цикл 56 (Нано)

64 біт гірший випадок - 20 цифр.

Петлі: 100 000 000, Час витрати: 13,148 (Міллі), Час за цикл 131 (Нано)

Як це працює!

Ми виконуємо техніку «Розділити і перемогти», і як тільки ми зараз встановимо максимальну довжину рядка, просто встановимо кожне значення символу окремо. Як показано у вищевказаних тестах на швидкість, більші довжини отримують великі штрафні показники, але це все ще набагато швидше, ніж оригінальний метод циклу, і жоден код насправді не змінився між двома методами, а потім циклічне використання вже не використовується.

Звідси в імені я повертаю зміщення замість цього, і я не редагую буфер масивів знаків, а починаю оновлення даних вершин, і функція має додатковий параметр для зміщення, тому не ініціалізується до -1.




0

Ви також можете використовувати кастинг.

приклад:

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

1
Що робити, якщо значення від’ємне чи немає цифри?
— Ziya ERKOC
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.