【问题标题】:how to convert from int to char*?如何从 int 转换为 char*?
【发布时间】:2012-06-06 12:21:57
【问题描述】:

我知道的唯一方法是:

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

但是有没有打字少的方法?

【问题讨论】:

  • 为什么要 C 字符串而不是 C++ 字符串?
  • 使用sprintf

标签: c++ integer const-char


【解决方案1】:

将我们的整数值转换为 std::string 以便我们知道多长(多少位数)。

然后我们创建字符串字母大小+1的字符数组长度,所以我们可以将我们的值复制到字符串然后是字符数组。

#include <string>

char* intToStr(int data) {
    std::string strData = std::to_string(data);

    char* temp = new char[strData.length() + 1];
    strcpy(temp, strData.c_str());

   return temp;
}

【讨论】:

  • 请不要只发布原始代码作为答案。始终解释代码的作用和原因。
  • 您好,谢谢您的回答!你能解释一下吗?这将有助于 OP 和未来的读者:)
【解决方案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(Milli),每个循环的时间 13(Nano)

Worse Case 20 数字值。

循环数:100,000,000,花费时间:22,656(Milli),每循环时间 226(纳米)

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

最佳情况 1 位数值。

循环:100,000,000,花费时间:427(Milli),每循环时间 4(Nano)

32 位最坏情况 - 11 位值。

循环:100,000,000,花费的时间:1,991(Milli),每个循环的时间 19(Nano)

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

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

64 位更坏情况 - 20 位数值。

循环:100,000,000,花费时间:13,148(Milli),每循环时间 131(Nano)

工作原理!

我们执行分而治之的技术,一旦我们现在获得了字符串的最大长度,我们只需单独设置每个字符值。如上面的速度测试所示,较大的长度会导致较大的性能损失,但它仍然比原始循环方法快得多,并且在两种方法之间实际上没有代码更改,除非循环不再使用。

在我的使用中,因此名称我返回偏移量,并且我不编辑 char 数组的缓冲区,而是开始更新顶点数据,并且该函数有一个额外的偏移量参数,因此它没有初始化为 -1。

【讨论】:

    【解决方案3】:
    • 在 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
      

    【讨论】:

    • 第一部分实际上并没有回答这个问题(尽管这是很好的有用信息,因为我不知道该功能)
    • 更好:) 另外,我最好再次阅读有关 c++11 的更多信息。我知道大功能,但这让我意识到我可能错过了更多小功能。
    • @Adambean:为什么它“不应该涉及 std::string”? .默认情况下应该使用std::string,而不是char*
    • std::string 并不总是可用的,尤其是对于较旧的项目。许多 C++ 游戏也仍然远离 std::string。从 int 到 std::string 到 char* 与从 int 到 char* 不同。
    • @Adambean:如果它是 C++,那么我将假设 std::string 默认情况下可用,除非在问题本身中明确指定。说得通?另外,由于问题本身使用了std::string(和std::stringstream),所以你没有太多不同意的理由。
    【解决方案4】:

    这可能有点晚了,但我也遇到了同样的问题。 在 C++17 中使用“charconv”库解决了转换为 char 的问题。

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

    【讨论】:

      【解决方案5】:

      您也可以使用强制转换。

      示例:

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

      【讨论】:

      • 如果值为负数或不是数字怎么办?
      【解决方案6】:

      看到这个答案https://stackoverflow.com/a/23010605/2760919

      对于您的情况,只需将 snprintf 中的类型从 long ("%ld") 更改为 int ("%n")。

      【讨论】:

        【解决方案7】:

        我认为你可以使用 sprintf :

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

        【讨论】:

        • 你应该把 char* 改成 char,现在 numberstring 是一个指针数组
        • 另外,您需要 12 个字符才能将 32 位整数转换为以 nul 结尾的 base-10 表示。 -2147483647 10 是不够的。
        • 解释一下如何? (((sizeof number) * CHAR_BIT) + 2)/3 + 2 看起来像魔法......
        • 虽然它可以工作,但这个例子是创建一个指向指针char *numberString[someNumber]的指针。做起来更简单:int number = 123; char numberstring[10]; sprintf(numberstring, "%d", number); printf("the number is: %s \n", (char*)numberstring);
        • @MikeS 你明白了吗? :P 我真的很想知道它是如何工作的
        【解决方案8】:

        我不会在最后一行中对 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();更好?
        • 是的。 c_str 给你一个指向字符串对象内部缓冲区的指针。如果您抛弃 const,您或其他程序员可能会认为可以通过非常量变量更改缓冲区。但事实并非如此。原始字符串对象对这些更改一无所知。另一方面,字符串仍然拥有缓冲区。如果字符串对象超出范围,则指针后面的内存将被字符串对象析构函数删除,留下一个悬空指针。复制操作消除了这两个问题。
        • 或者,std::vector&lt;char&gt; temp_vec(temp_str.begin(), temp_str.end()); temp_vec.push_back(0); char *char_type = &amp;vec[0];。这为您提供了可变内存,当然,只要您想使用指针,您仍然需要保持向量处于活动状态。
        • 或者只使用 string 并且不要打扰旧的、普通的、愚蠢的 char * 来自旧的、普通的 C。
        • @Griwes:问题是如何到达char*,而不是“从 C++ 调用现有的用 C 语言编写的库有什么意义,或者我应该用 C++ 重新实现它们吗?” ;-p
        【解决方案9】:

        C 风格的解决方案可能是使用itoa,但更好的方法是使用sprintf / snprintf 将此数字打印成字符串。检查这个问题:How to convert an integer to a string portably?

        注意itoa函数在ANSI-C中没有定义,也不是C++的一部分,但被一些编译器支持。这是一个非标准函数,因此你应该避免使用它.也检查这个问题:Alternative to itoa() for converting integer to string C++?

        另请注意,在使用 C++ 编程时编写 C 风格的代码被认为是不好的做法,有时被称为“可怕的风格”。你真的想把它转换成 C 风格的char* 字符串吗? :)

        【讨论】:

          【解决方案10】:

          你可以使用提升

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

          【讨论】:

            猜你喜欢
            • 2017-03-21
            • 2014-09-20
            • 2014-05-04
            • 1970-01-01
            • 2020-04-05
            • 2014-12-27
            • 1970-01-01
            • 2011-04-09
            相关资源
            最近更新 更多