Вопрос по c++ – как конфертировать из int в char *?

85

Единственный способ, которым я знаю, это:

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

Но есть ли способ с меньшим набором текста?

use Sprintf Kasma
почему ты хочешь C-строку вместо C ++-строки? KillianDS

Ваш Ответ

9   ответов
109

В 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
Первая часть фактически не отвечает на вопрос (хотя это хорошая полезная информация, так как я не знал об этой функции) jcoder
Лучше :) Плюс я лучше пойду читать больше о c ++ 11 снова. Я знаю о больших возможностях, но это заставило меня понять, что, возможно, есть и более мелкие, которые я пропустил. jcoder
@ Adambean: Почему он "не должен включать std :: string"? , Надо использоватьstd::string по умолчанию вместоchar*. Nawaz
std :: string не всегда доступна, особенно для старых проектов. Множество игр на C ++ также остаются в стороне от std :: string. Переход от int к std :: string к char * - это не то же самое, что int к char *. Adambean
@ Adambean: Если это C ++, то я собираюсь предположить, чтоstd::string доступно по умолчанию, если это не указано явно в самом вопросе. Имеет смысл? Кроме того, поскольку сам вопрос используетstd::string (а такжеstd::stringstream), тогда у тебя нет особых причин не соглашаться с этим. Nawaz
8

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

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

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

int number = 33;
char* numberstring[(((sizeof number) * CHAR_BIT) + 2)/3 + 2];
sprintf(numberstring, "%d", number);
Вы должны изменить char * на char, прямо сейчас numberstring - это массив указателей josefx
Кроме того, вам нужно 12 символов для преобразования 32-разрядного целого числа в представление base-10 с нулевым символом в конце. 10 недостаточно для-2147483647. Steve Jessop
Как насчет объяснения?(((sizeof number) * CHAR_BIT) + 2)/3 + 2 выглядит как волшебство ... Mike S
5

itoa, но лучше вывести это число в строку, используяsprintf / snprintf. Проверьте этот вопрос: Как преобразовать целое число в строку переносимо?

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

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

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
Да. c_str дает вам указатель на внутренний буфер строкового объекта. Если вы отбрасываете const, вы или другой программист могли бы подумать, что можно менять буфер через неконстантную переменную. Но это не так. Исходный строковый объект ничего не знает об этих изменениях. С другой стороны, строка все еще владеет буфером. Если строковый объект выходит из области видимости, память за указателем удаляется деструктором строковых объектов, оставляя вас с висящим указателем. Операция копирования устраняет обе проблемы. user331471
Альтернативно,std::vector<char> temp_vec(temp_str.begin(), temp_str.end()); temp_vec.push_back(0); char *char_type = &vec[0];. Это дает вам изменчивую память, хотя, конечно, вам все равно нужно поддерживать вектор в течение тех пор, пока вы хотите использовать указатель. Steve Jessop
Или просто используйstring и не беспокойся о старых, простых, глупыхchar * из старого, простого C. <кусочки пламени предназначены> Griwes
@ Griwes: вопрос в том, как добраться доchar*, а не "есть ли смысл вызывать из C ++ существующие библиотеки, написанные на C, или я должен заново реализовать их в C ++?" ;- Steve Jessop
1

https: //stackoverflow.com/a/23010605/276091

Для вашего случая просто измените тип в snprintf с long ("% ld") на int ("% n").

1

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

пример

string s;
int value = 3;
s.push_back((char)('0' + value));
Что если значение отрицательное или не цифра? Ziya ERKOC
1

но у меня тоже была такая же проблема. Преобразование в char было решено в C ++ 17 с помощью библиотеки "charconv".

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

0

мне нужно что-то, что делало то, что задает этот вопрос, но мне нужно было БЫСТРО! К сожалению, «лучший» способ это около 600 строк кода !!! Прошу прощения за название, которое не имеет никакого отношения к тому, что он делает. Собственное имя было Integer64ToCharArray (значение int64_t);

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

Не стесняйтесь попробовать очистить этот код без ущерба для производительности.

Input: Любое 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.

Похожие вопросы