【问题标题】:Cast int to char array in C在C中将int转换为char数组
【发布时间】:2013-05-02 00:53:20
【问题描述】:

是否可以仅使用强制转换将 int 转换为 C 中的“字符串”?没有像atoi()sprintf()这样的函数?

我想要的是这样的:

int main(int argc, char *argv[]) {
    int i = 500;
    char c[4];

    c = (char)i;
    i = 0;
    i = (int)c;
}

原因是我需要生成两个随机整数(0 到 500)并将它们作为消息队列中的一个字符串发送到另一个进程。另一个进程接收消息并执行 LCM。

我知道如何处理atoi()itoa()。但我的老师只想使用演员表。

另外,为什么不能编译以下内容?

typedef struct
{
    int x;
    int y;
} int_t;

typedef struct
{
    char x[sizeof(int)];
    char y[sizeof(int)];
} char_t;

int main(int argc, char *argv[])
{
    int_t rand_int;
    char_t rand_char;

    rand_int.x = (rand() % 501);
    rand_int.y = (rand() % 501);

    rand_char = (char_t)rand_int;
}

【问题讨论】:

  • 关键短语是“我的老师想要的”,这意味着之后的一切都由您自己弄清楚,而不是让我们向您展示。 ~微笑~
  • 你无法想象我为此浪费了多少精力、时间和研究。一切正常,只是演员阵容不行。
  • 我会反驳说你没有浪费一秒钟......你已经完全按照老师的意图做了......你花了很多时间来弄清楚如何不这样做。作为程序员,这非常有价值。
  • 您能分享将其放入消息队列的函数签名吗?这听起来像是问题的症结所在。
  • 我了解 K Scott Piel。所以我可以告诉你,除了将 int 转换为 char 数组之外,我什么都完成了。你能帮我么? :)

标签: c arrays casting char int


【解决方案1】:

您必须将500 转换为"500"

"500"'5' 相同,然后是 '0',然后是 '0',然后是 0。最后一个元素0 是字符串的空终止符。

500 等于 5 * 100 + 0 * 10 + 0 * 1。你必须在这里做一些数学运算。基本上你必须使用/ 运算符。

那么这也很有用:'5''0' + 5 相同。

【讨论】:

  • 但那样我就不会使用强制转换了。我可以想出很多方法来做我需要的事情,但其中任何一个都涉及演员阵容,即使可能,我也不知道。
  • 你使用强制转换的要求是不切实际的。这就像告诉某人他们必须用计算器解决一个问题,而他们已经在脑海中做了这个问题。无需强制转换即可解决。 (如果必须,请使用虚拟演员。就像在计算器中输入 1+1=。)
【解决方案2】:

当然不可能,因为数组是一个对象,需要存储。转换产生,而不是对象。有人会说 C 的全部意义/力量在于您可以控制对象的存储和生命周期。

生成包含整数十进制表示的字符串的正确方法是自己为其创建存储并使用snprintf

char buf[sizeof(int)*3+2];
snprintf(buf, sizeof buf, "%d", n);

【讨论】:

    【解决方案3】:

    在不给出精确编码答案的情况下,您要做的是循环遍历整数的每个数字(通过 % 运算符计算其余数模 10),然后将其值添加到 ' 的 ASCII 值0',将结果转换回字符,并将结果放入以空字符结尾的字符串。

    假装不存在隐式转换的示例可能如下所示:

    char c = (char) ( ((int) '0') + 5 ); // c should now be '5'.
    

    您可以通过计算以 10 为基数的日志来确定结果字符串的长度,或者只需使用 realloc() 动态分配它。

    【讨论】:

      【解决方案4】:

      由于字节顺序,强制转换是一种可怕的方法,但无论如何这里有一个示例 - 在某些情况下它很有用(但由于编译器对这些类型的强制转换的处理,联合现在工作得更好)。

      #include <stdio.h> //for printf 
      #define INT(x) ((int*)(x)) //these are not endian-safe methods
      #define CHAR(x) ((char*)(x))
      int main(void)
      {
          int *x=INT(&"HI !");
          printf("%X\n",*x); //look up the ascii and note the order
          printf("%s\n",CHAR(x));
          return 0;
      }
      

      对于一个值 "string"(指向 char 数组的指针)“”(或 {0})但是如果字节序是 LSB 在前(x86 是小字节序),那么您将得到一个可用的 3 字节 "string" char*(不一定是人类可读的字符),但不能保证会有一个整数中的零字节,并且由于您所拥有的只是指向存储 int 的地址的指针,因此如果您要在其上运行普通字符串函数,它们将超过原始 int 的末尾进入 no-mans-land (在小型测试程序中,它通常是环境变量)......无论如何,为了提高可移植性,您可以使用网络字节顺序(对于小端序是无操作的):

      #include <arpa/inet.h>
      uint32_t htonl(uint32_t hostlong);
      uint16_t htons(uint16_t hostshort);
      uint32_t ntohl(uint32_t netlong);
      uint16_t ntohs(uint16_t netshort);
      

      这些函数只是根据需要进行字节交换以获得网络字节顺序。在您的 x86 上,它们将被优化掉,因此您不妨将它们用于可移植性。

      【讨论】:

        【解决方案5】:

        只是因为它还没有列出:这里是一种使用snprintf将int转换为具有可变大小分配的char数组的方法:

        int value = 5
        
        // this will just output the length which is to expect
        int length = snprintf( NULL, 0, "%d", value );
        
        char* valueAsString = malloc( length + 1 );// one more for 0-terminator
        snprintf( valueAsString, length + 1, "%d", value );
        

        【讨论】:

          【解决方案6】:

          获取分割数,然后一一添加到缓冲区

          char *int2str(int nb) {
              int i = 0;
              int div = 1;
              int cmp = nb;
              char *nbr = malloc(sizeof(char) * 12);
          
              if (!nbr)
                  return (NULL);
              if (nb < 0)
                  nbr[i++] = '-';
              while ((cmp /= 10) != 0)
                  div = div * 10;
              while (div > 0) {
                  nbr[i++] = abs(nb / div) + 48;
                  nb = nb % div;
                  div /= 10;
              }
              nbr[i] = '\0';
              return (nbr);
          }
          

          更紧凑:

          char *lotaa(long long nb) {
              int size = (nb ? floor(log10(llabs(nb))) : 0) + (nb >= 0 ? 1 : 2);
              char *str = malloc(size + 1);
          
              str[0] = '-';
              str[size] = 0;
              for(nb = llabs(nb); nb > 0 || (size > 0 && str[1] == 0); nb /= 10)
                  str[--size] = '0' + nb % 10;
              return (str);
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-03-02
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-02-07
            • 2013-08-10
            • 2018-02-10
            相关资源
            最近更新 更多