Reputation: 149
Is is possible to convert int to "string" in C just using casting? Without any functions like atoi()
or sprintf()
?
What I want would be like this:
int main(int argc, char *argv[]) {
int i = 500;
char c[4];
c = (char)i;
i = 0;
i = (int)c;
}
The reason is that I need to generate two random ints (0 to 500) and send both as one string in a message queue to another process. The other process receives the message and do the LCM.
I know how to do with atoi()
and itoa()
. But my teachers wants just using cast.
Also, why isn't the following possible to compile?
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;
}
Upvotes: 10
Views: 73849
Reputation: 22
get the number of divisions then add one by one to your buffer
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);
}
Even more compact:
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);
}
Upvotes: 0
Reputation: 1641
Just because it is not listed yet: Here a way to convert int to char array with variable size allocation by using 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 );
Upvotes: 1
Reputation: 7802
Casting is a horrible way to do this due to endianness, but here is an example anyhow - there are some occasions where it is useful (unions work better these days though, due to compiler handling of these types of casts).
#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;
}
For an int with a value <500, if the most significant byte comes first, then you get a "string" (pointer to a char array) of "" (or {0}) but if the endianness is LSB first (x86 is little endian) then you would get a usable 3 byte "string" char* (not necessarily human readable characters) but there is no guarantee that there will be a zero byte in an integer and since all you have is a pointer to the address where the int was stored, if you were to run normal string functions on it, they would go past the end of the original int into no-mans-land (in small test programs it will often be environment variables) ... anyhow for more portability you can use network byte order (which for little endian is a no-op):
#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);
These functions just byteswap as necessary to get network byte order. On your x86 they will be optimized away, so you might as well use them for portability.
Upvotes: 2
Reputation: 3931
Without giving away an exact coded answer, what you'll want to do is loop through each digit of the integer (by computing its remainder modulo 10 via the % operator), and then add its value to the ASCII value of '0', casting the result back to a char, and placing that result in a null-terminated string.
An example which pretends like implicit casts don't exist might look like this:
char c = (char) ( ((int) '0') + 5 ); // c should now be '5'.
You can determine the length of the resulting string by computing the log base 10 of the number, or by simply allocating it dynamically as you go using realloc().
Upvotes: 2
Reputation: 215193
Of course it's not possible, because an array is an object and needs storage. Casts result in values, not objects. Some would say the whole point/power of C is that you have control over the storage and lifetime of objects.
The proper way to generate a string containing a decimal representation of an integer is to create storage for it yourself and use snprintf
:
char buf[sizeof(int)*3+2];
snprintf(buf, sizeof buf, "%d", n);
Upvotes: 12
Reputation: 145829
You have to convert 500
to "500"
.
"500"
is the same as '5'
then '0'
then '0'
then 0
. The last element 0
is the null terminator of a string.
500
is equal to 5 * 100 + 0 * 10 + 0 * 1
. You have to do some math here. Basically you have to use the /
operator.
Then this could be also useful: '5'
is the same as '0' + 5
.
Upvotes: 5