9

是否可以仅使用强制转换将 int 转换为 C 中的“字符串”?没有类似atoi()or的任何功能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()and 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;
}
4

6 回答 6

11

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

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

char buf[sizeof(int)*3+2];
snprintf(buf, sizeof buf, "%d", n);
于 2013-05-07T23:14:53.280 回答
5

您必须转换500"500".

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

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

那么这也很有用:'5''0' + 5.

于 2013-05-07T22:40:29.500 回答
2

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

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

对于值 <500 的 int,如果最重要的字节首先出现,那么你会得到一个""(或 {0})的“字符串”(指向 char 数组的指针),但如果字节顺序是 LSB 在前(x86 是little endian) 那么你会得到一个可用的 3 字节“字符串” char* (不一定是人类可读的字符),但不能保证整数中会有一个零字节,因为你所拥有的只是一个指向地址的指针int 已存储,如果您要在其上运行正常的字符串函数,它们会越过原始 int 的末尾进入无人区(在小型测试程序中,它通常是环境变量)......无论如何更多可移植性您可以使用网络字节顺序(对于小端序是无操作的):

#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 上,它们将被优化掉,因此您不妨将它们用于可移植性。

于 2014-07-20T05:30:32.467 回答
2

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

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

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

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

于 2013-05-16T22:02:21.767 回答
1

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

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 );
于 2016-08-10T11:30:08.667 回答
0

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

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);
}
于 2019-04-02T15:35:48.220 回答