Chuyển đổi bất cứ thứ gì thành một chuỗi nên 1) phân bổ chuỗi kết quả hoặc 2) truyền vào char *
đích và kích thước. Mã mẫu dưới đây:
Cả hai làm việc cho tất cả int
bao gồm INT_MIN
. Họ cung cấp một đầu ra nhất quán không giống như snprintf()
phụ thuộc vào miền địa phương hiện tại.
Phương pháp 1: Trả NULL
về bộ nhớ ngoài.
#define INT_DECIMAL_STRING_SIZE(int_type) ((CHAR_BIT*sizeof(int_type)-1)*10/33+3)
char *int_to_string_alloc(int x) {
int i = x;
char buf[INT_DECIMAL_STRING_SIZE(int)];
char *p = &buf[sizeof buf - 1];
*p = '\0';
if (i >= 0) {
i = -i;
}
do {
p--;
*p = (char) ('0' - i % 10);
i /= 10;
} while (i);
if (x < 0) {
p--;
*p = '-';
}
size_t len = (size_t) (&buf[sizeof buf] - p);
char *s = malloc(len);
if (s) {
memcpy(s, p, len);
}
return s;
}
Phương pháp 2: Nó trả về NULL
nếu bộ đệm quá nhỏ.
static char *int_to_string_helper(char *dest, size_t n, int x) {
if (n == 0) {
return NULL;
}
if (x <= -10) {
dest = int_to_string_helper(dest, n - 1, x / 10);
if (dest == NULL) return NULL;
}
*dest = (char) ('0' - x % 10);
return dest + 1;
}
char *int_to_string(char *dest, size_t n, int x) {
char *p = dest;
if (n == 0) {
return NULL;
}
n--;
if (x < 0) {
if (n == 0) return NULL;
n--;
*p++ = '-';
} else {
x = -x;
}
p = int_to_string_helper(p, n, x);
if (p == NULL) return NULL;
*p = 0;
return dest;
}
[Chỉnh sửa] theo yêu cầu của @Alter Mann
(CHAR_BIT*sizeof(int_type)-1)*10/33+3
ít nhất là số lượng tối đa char
cần thiết để mã hóa một số loại số nguyên đã ký dưới dạng một chuỗi bao gồm một dấu âm, chữ số và ký tự null tùy chọn ..
Số lượng bit không dấu trong một số nguyên đã ký không nhiều hơn CHAR_BIT*sizeof(int_type)-1
. Một đại diện cơ sở 10 của một n
số nhị phân -bit mất đến n*log10(2) + 1
chữ số. 10/33
là nhiều hơn một chút log10(2)
. +1 cho ký hiệu char
và +1 cho ký tự null. Các phân số khác có thể được sử dụng như 28/93.
Phương pháp 3: Nếu một người muốn sống ở rìa và tràn bộ đệm không phải là vấn đề đáng lo ngại, một giải pháp C99 đơn giản hoặc mới hơn sẽ xử lý tất cả int
.
#include <limits.h>
#include <stdio.h>
static char *itoa_simple_helper(char *dest, int i) {
if (i <= -10) {
dest = itoa_simple_helper(dest, i/10);
}
*dest++ = '0' - i%10;
return dest;
}
char *itoa_simple(char *dest, int i) {
char *s = dest;
if (i < 0) {
*s++ = '-';
} else {
i = -i;
}
*itoa_simple_helper(s, i) = '\0';
return dest;
}
int main() {
char s[100];
puts(itoa_simple(s, 0));
puts(itoa_simple(s, 1));
puts(itoa_simple(s, -1));
puts(itoa_simple(s, 12345));
puts(itoa_simple(s, INT_MAX-1));
puts(itoa_simple(s, INT_MAX));
puts(itoa_simple(s, INT_MIN+1));
puts(itoa_simple(s, INT_MIN));
}
Sản lượng mẫu
0
1
-1
12345
2147483646
2147483647
-2147483647
-2147483648
printf
hoặc một trong những anh em họ của nó nên thực hiện mánh khóe