如何从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 2012年

1
使用的sprintf
Kasma

Answers:


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 2012年

1
@Adambean:为什么它“不应该涉及std :: string”?。std::string默认情况下,应使用而不是char*
纳瓦兹

1
std :: string并不总是可用,尤其是对于较旧的项目。许多C ++游戏仍然远离std :: string。从int到std :: string到char *与从int到char *不同。
Adambean '16

1
@Adambean:如果是C ++,那么我将假定std::string默认情况下可用,除非在问题本身中明确指定了它。说得通?另外,由于问题本身使用std::string(和std::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 2012年

1
同样,您需要12个字符才能将32位整数转换为以nul终止的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风格的代码被认为是不好的作法,有时被称为“令人作呕的风格”。您是否真的要将其转换为C样式的char*字符串?:)


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,您或其他程序员可能会认为可以通过非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 value);

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(Milli),每循环时间226(Nano

新的设计速度测试:(AddDynamicallyToBuffer();

最佳情况下为1位数。

循环次数:100,000,000,花费的时间:427(毫),每个循环的时间4(纳米)

32位最坏情况-11位值。

循环次数:100,000,000,花费的时间:1,991(毫),每个循环的时间19(纳米)

负1万亿美元最坏情况-14位数值。

循环数:100,000,000,耗时:5,681(Milli),每循环时间56(Nano)

64位情况更糟-20位数字值。

循环次数:100,000,000,耗时:13,148(Milli),每循环时间131(Nano)

这个怎么运作!

我们执行分而治之的方法,现在一旦我们确定了字符串的最大长度,我们就可以简单地分别设置每个字符值。如上面的速度测试所示,较大的长度会带来较大的性能损失,但是它仍然比原始循环方法快得多,并且在这两种方法之间实际上没有任何代码更改,只是不再使用循环。

在我的用法中,因此我改用名称来返回offset,并且我不编辑char数组的缓冲区,而是开始更新顶点数据,并且该函数具有offset的附加参数,因此未初始化为-1。




0

您也可以使用投射。

例:

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

1
如果值是负数或不是数字怎么办?
Ziya ERKOC
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.