как преобразовать из 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

Ответы:


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 01

1
Лучше :) К тому же, мне лучше еще раз прочитать о С ++ 11. Я знаю о важных функциях, но это заставило меня понять, что, вероятно, я упустил и другие мелкие.
jcoder 01

1
@Adambean: Почему он «не должен включать std :: string»? . Следует использовать std::stringпо умолчанию вместо char*.
Nawaz

1
std :: string не всегда доступен, особенно для старых проектов. Многие игры на C ++ также избегают std :: string. Переход от int к std :: string к char * не то же самое, что от int к char *.
Adambean

1
@Adambean: Если это C ++, то я предполагаю, что std::stringон доступен по умолчанию, если это явно не указано в самом вопросе. Имеет смысл? Кроме того, поскольку в самом вопросе используется std::stringstd::stringstream), у вас нет особых причин не соглашаться с этим.
Nawaz

11

Я думаю, вы можете использовать sprintf:

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

1
вы должны изменить char * на char, сейчас numberstring - это массив указателей
josefx 01

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

11
Как насчет объяснения? (((sizeof number) * CHAR_BIT) + 2)/3 + 2похоже на волшебство ...
Mike S

7

Вы можете использовать ускорение

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

5

Можно было бы использовать решение в стиле C itoa, но лучше вывести это число в строку с помощью sprintf/snprintf . Отметьте этот вопрос: как переносимо преобразовать целое число в строку?

Обратите внимание, что itoaфункция не определена в ANSI-C и не является частью C ++, но поддерживается некоторыми компиляторами. Это нестандартная функция, поэтому вам следует избегать ее использования. Проверьте и этот вопрос: Альтернатива itoa () для преобразования целого числа в строку C ++?

Также обратите внимание, что написание кода в стиле C при программировании на C ++ считается плохой практикой и иногда называется «ужасным стилем». Вы действительно хотите преобразовать его в char*строку C-стиля ? :)


5

Я бы не стал отбрасывать константу в последней строке, потому что она есть не просто так. Если вы не можете жить с 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 01

1
Да. c_str дает вам указатель на внутренний буфер строкового объекта. Если вы отбросите константу, вы или другой программист можете подумать, что можно изменить буфер с помощью неконстантной переменной. Но это не так. Исходный строковый объект ничего не знает об этих изменениях. С другой стороны, строка по-прежнему владеет буфером. Если строковый объект выходит за пределы области видимости, память за указателем удаляется деструктором строковых объектов, оставляя вам висящий указатель. Операция копирования устраняет обе проблемы.
user331471 01

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 01

@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-значное значение.

Циклов: 100000000, Затраченное время: 1381 (Милли), Время на цикл 13 (Нано)

В худшем случае 20-значное значение.

Циклов: 100000000, Затраченное время: 22656 (Милли), Время на цикл 226 (Нано

Новые тесты скорости проектирования: ( AddDynamicallyToBuffer (); )

В лучшем случае 1-значное значение.

Циклов: 100000000, Затраченное время: 427 (Милли), Время на цикл 4 (Нано)

32-битный наихудший случай - 11-значное значение.

Петли: 100000000, затраченное время: 1991 (милли), время на цикл 19 (нано)

Отрицательный 1 триллион наихудший случай - 14-значное значение.

Циклы: 100000000, затраченное время: 5681 (милли), время на цикл 56 (нано)

64-битный наихудший случай - 20-значное значение.

Циклов: 100000000, Затраченное время: 13148 (Милли), Время на цикл 131 (Нано)

Как это устроено!

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

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




0

Вы также можете использовать кастинг.

пример:

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

2
Что делать, если значение отрицательное или не цифра?
Зия ЭРКОЦ 03
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.