Convert integer into an array
I am working on a C program, and I am coming across a small problem. I don't know how to convert an integer (say 2007) into a char array. Is there a function in the C libraries to do that for me?
To clarify, I'd like to take 2007 and store it in some char array[4] ={ '2', '0', '0', '7', '\0' };
I was thinking something like sprintf, but I'm not sure. Anyways, any help/hints开发者_运维百科 would be appreciated.
Thanks, Michael
You can do that with sprintf
, or more safely snprintf
.
Here's a contrived example:
#include <stdio.h>
#define MAX_LEN 5
char str[MAX_LEN];
snprintf(str, MAX_LEN, "%d", 2007);
Use snprintf()
and be sure allocate the proper amount of space to hold numbers up to 2^(sizeof(int)*CHAR_BIT). On a 64-bit machine, that will be 20 digit characters, plus 1 for the NULL terminator.
#include <stdio.h>
#define MAX_DIGITS 20
int n = 2007;
char str[MAX_DIGITS+1];
snprintf(str, MAX_DIGITS+1, "%d", n);
As others have said, you should look at sprintf()
or snprintf()
. Assuming you are trying to convert an integral type T
to such an array, the interesting bit is to figure out the size of the buffer for the array.
First, the number of digits in a number's decimal representation is ⌊log10n+1⌋. The maximum possible value of an unsigned integral type T
can be represented in nbits = CHAR_BIT*sizeof(T)
binary bits, which will need ⌊log102nbits⌋+1 decimal digits.
log102nbits = nbits×log102 = nbits×log(2)/log(10).
28/93
is a very good1 rational approximation of log(2)/log(10)
(0.30107526881720431 vs 0.30102999566398114).
So, using the above, we get our expression for the number of digits:
CHAR_BIT * sizeof(T) * 28 / 93 + 1
For signed numbers, we need to add 1 more for the -
sign, and we need to add 1 for the terminating 0
. So we get:
#include <limits.h>
/* Figure out the maximum number of characters including the
terminating 0 to represent the numbers in integral type T */
#define SZ(T) (CHAR_BIT * sizeof(T) * 28 / 93 + 3)
So we can do:
char array[SZ(int)];
sprintf(array, "%d", n);
And we are sure that array
has enough space. We don't have to worry about snprintf()
or malloc()
/realloc()
and free()
combination either.
Here is a complete program using the above:
#include <stdio.h>
#include <limits.h>
/* Figure out the maximum number of characters including the
terminating 0 to represent the numbers in integral type T */
#define SZ(T) (CHAR_BIT * sizeof(T) * 28 / 93 + 3)
#define PRINT(x) do \
{ \
printf("%s: %lu\n", #x, (unsigned long)SZ(x)); \
} while (0)
int main(void)
{
PRINT(int);
PRINT(long);
PRINT(size_t);
return 0;
}
1or good enough for this purpose.
#include <stdio.h>
char array[5];
sprintf(array, "%d", 2007);
...done.
Note that sprintf is not overflow safe, so if you have a number of 5 or more digits you'll have a problem. Note also that the converted number will be followed by a terminating \0
.
The classic way is itoa
. Or you can use snprintf
to get more control.
There is a nonstandard, but well-supported as I undertand it, function itoa
- the opposite of atoi
.
Example:
char *a = malloc(10 * sizeof(char));
itoa(2007, a, 2007);
sprintf
also works:
char *a = malloc(10 * sizeof(char));
sprintf(a, "%d", 2007);
int n = 2007;
char a[100];
sprintf( a, "%d", n );
Use snprintf
:
// value is int;
// buf is char *;
// length is space available in buf
snprintf(buf, length, "%d", value)
snprintf
has the advantage of being standard and giving your more flexibility over the formatting as well as being safe.
You could also use itoa
but be warned that it is not part of the standard. Most implementations have it though.
Usage:
// value is int;
// buf is char *;
itoa(value, buf, 10);
An interesting question is: how much space do you allocate for buf
? We note the following. With sizeof(int)
bytes per int
and eight bits per byte, the maximum value is approximately 2^(CHAR_BIT * sizeof(int) - 1)
(-1
is for sign bit). Therefore we need space to hold
floor(log_10(2^(CHAR_BIT * sizeof(int) - 1)) + 1
digits. But don't forget the sign and null terminator! So the maximum length of an integer representable here is
floor(log_10(2^(CHAR_BIT * sizeof(int) - 1)) + 3.
Of course, this could be wasting space if our values are small. To find out how much space a specific value needs:
floor(log_10(abs(value))) + 1 + (value < 0 ? 1 : 0) + 1
精彩评论