How can I convert a long variable to a char[] variable without using library functions?
2 Answers
Working example (1) - thread-safe, requires min. buffsize = 40.
static const char *
xllitoa(long long int x, char *buff)
{
char *p = buff + 40;
int sign = 0;
*(p--) = 0;
if (x < 0) sign = 1;
else x = -x;
do { *(p--) = -(x % 10) + '0'; x /= 10; } while(x);
if (sign) *(p--) = '-';
return (const char *)(p+1);
}
Working example (2) - not thread-safe
static const char *
xllitoa(long long int x)
{
static char buff[40];
char *p = buff + 40;
int sign = 0;
*(p--) = 0;
if (x < 0) sign = 1;
else x = -x;
do { *(p--) = -(x % 10) + '0'; x /= 10; } while(x);
if (sign) *(p--) = '-';
return (const char *)(p+1);
}
Many thanks to reviewers. Now it accepts LLONG_MAX and LLONG_MIN as well.
10 Comments
Serge Ballesta
+1 because IMHO it is the solution, but you do not use system calls ... was the question badly asked ?
jfs
use
'0' instead of 48. C99 guarantees that '1' is next to '0'. '0' might differ from 48 (EBCDIC?). If long long is 128bit on some (future?) system then you need bufsize=40 (including '\0' at the end). Perheps some formula with sizeof(long long) should be used.Jonathan Leffler
Note that in C99 you can document the 'buffer must be 32 characters' requirement explicitly (if obscurely) with:
const char *xllitoa(long long int x, char buff[static 32]) { … }.chux
xllitoa() fails in 2 ways. 1) It does not terminate the buffer (But then OP said char array and not "string" Hmmmm. 2) It does not work for LLONG_MIN.chux
@soerium C specifies
LLONG_MIN <= LONG_MIN. Since they could be the same value (they are on my gcc machine), failing LLONG_MIN as this code does, also can fail OP's LONG_MIN. Going to long long to avoid a problem with LONG_MIN does not always work. |
After accept answer that works for all values LONG_MIN to LONG_MAX.
This uses a helper function to recursive work with negative values of n. By using negative values, there is no problem with LONG_MIN.
static char *ltostr_helper(long n, char *dest) {
if (n <= -10)
dest = ltostr_helper(n / 10, dest);
*dest++ = (char) ('0' - n % 10);
return dest; // return pointer to end
}
void ltostr(long n, char *dest) {
if (n < 0) {
*dest++ = '-';
} else {
n = -n;
}
*ltostr_helper(n, dest) = '\0';
}
int main(void) {
char buf[sizeof(long) * CHAR_BIT /3 + 3];// size buffer to our needs
ltostr(0, buf); printf("%s\n", buf);
ltostr(123, buf); printf("%s\n", buf);
ltostr(-123, buf); printf("%s\n", buf);
ltostr(LONG_MAX, buf); printf("%s\n", buf);
ltostr(LONG_MIN, buf); printf("%s\n", buf);
return 0;
}
Output
0
123
-123
9223372036854775807
-9223372036854775808
1 Comment
jfs
+1 for
sizeof(long). The negative values trick works for any allowed long representation: two's complement, one's complement, sign/magnitude representations.
stringtype; do you want a C string or a C++std::string?sprintfis not a system call.reallocfunction.longinteger value from some calculations into a text representation suitable for displaying to the user, or b) get at the raw bytes making up thatlongvalue by using achar[]to get at individual bytes, or c) something else entirely...