Как преобразовать int в строку в C?
Как вы конвертируете int
(целое число) в строку? Я пытаюсь сделать функцию, которая преобразует данные struct
в строку, чтобы сохранить его в файл.
13 ответов
РЕДАКТИРОВАТЬ: Как указано в комментарии, itoa()
не является стандартным, поэтому лучше использовать подход sprintf(), предложенный в ответе соперника!
Ты можешь использовать itoa()
функция для преобразования вашего целочисленного значения в строку.
Вот пример:
int num = 321;
char snum[5];
// convert 123 to string [buf]
itoa(num, snum, 10);
// print our string
printf("%s\n", snum);
Если вы хотите вывести свою структуру в файл, нет необходимости предварительно преобразовывать какое-либо значение. Вы можете просто использовать спецификацию формата printf, чтобы указать, как вывести ваши значения, и использовать любой из операторов семейства printf для вывода ваших данных.
Ты можешь использовать sprintf
сделать это, или, может быть, snprintf
если у вас есть:
char str[ENOUGH];
sprintf(str, "%d", 42);
Где количество символов (плюс завершающий символ) в str
можно рассчитать с помощью:
(int)((ceil(log10(num))+1)*sizeof(char))
Краткий ответ:
snprintf( str, size, "%d", x );
Чем дольше: для начала нужно выяснить достаточный размер. snprintf
говорит вам длину, если вы называете это с NULL, 0
в качестве первых параметров:
snprintf( NULL, 0, "%d", x );
Выделите еще один символ для нулевого терминатора.
int x = -42;
int length = snprintf( NULL, 0, "%d", x );
char* str = malloc( length + 1 );
snprintf( str, length + 1, "%d", x );
...
free(str);
Если работает для каждой строки формата, то вы можете конвертировать число с плавающей запятой или удвоить в строку, используя "%g"
, вы можете конвертировать int в гекс, используя "%x"
, и так далее.
Изучив различные версии itoa для gcc, я обнаружил, что наиболее гибкая версия, способная обрабатывать преобразования в двоичные, десятичные и шестнадцатеричные, как положительные, так и отрицательные, - четвертая версия, найденная на http://www.strudel.org.uk/itoa/. В то время как sprintf
/snprintf
имеют преимущества, они не будут обрабатывать отрицательные числа ни для чего, кроме десятичного преобразования. Поскольку ссылка выше отключена или больше не активна, я включил их 4-ю версию ниже:
char *
itoa (int value, char *result, int base)
{
// check that the base if valid
if (base < 2 || base > 36) { *result = '\0'; return result; }
char* ptr = result, *ptr1 = result, tmp_char;
int tmp_value;
do {
tmp_value = value;
value /= base;
*ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - value * base)];
} while ( value );
// Apply negative sign
if (tmp_value < 0) *ptr++ = '-';
*ptr-- = '\0';
while (ptr1 < ptr) {
tmp_char = *ptr;
*ptr--= *ptr1;
*ptr1++ = tmp_char;
}
return result;
}
Это старый, но вот другой способ.
#include <stdio.h>
#define atoa(x) #x
int main(int argc, char *argv[])
{
char *string = atoa(1234567890);
printf("%s\n", string);
return 0;
}
Преобразование чего-либо в строку должно либо 1) выделить результирующую строку, либо 2) передать в char *
назначение и размер. Пример кода ниже:
Оба работают для всех int
в том числе INT_MIN
, Они обеспечивают последовательный выход в отличие от snprintf()
который зависит от текущей локали.
Способ 1: возврат NULL
на нехватке памяти.
#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;
}
Способ 2: возвращается NULL
если буфер был слишком маленьким.
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;
}
[Изменить] как запрос @Alter Mann
(CHAR_BIT*sizeof(int_type)-1)*10/33+3
по крайней мере, максимальное количество char
необходимо закодировать некоторый целочисленный тип со знаком в виде строки, состоящей из необязательного отрицательного знака, цифр и нулевого символа.
Количество незнаковых битов в целом числе со знаком не более CHAR_BIT*sizeof(int_type)-1
, Base-10 представление n
двоичное число занимает до n*log10(2) + 1
цифры. 10/33
немного больше чем log10(2)
, +1 за знак char
и +1 для нулевого символа. Другие фракции могут быть использованы как 28/93.
Метод 3: Если кто-то хочет жить на грани, и переполнение буфера не является проблемой, следует простое решение C99 или более поздней версии, которое обрабатывает все 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));
}
Образец вывода
0
1
-1
12345
2147483646
2147483647
-2147483647
-2147483648
Если вы используете GCC, вы можете использовать расширение asprintf для GNU.
char* str;
asprintf (&str, "%i", 12313);
free(str);
sprintf возвращает байты и также добавляет нулевой байт:
# include <stdio.h>
# include <string.h>
int main() {
char buf[ 1024];
int n = sprintf( buf, "%d", 2415);
printf( "%s %d\n", buf, n);
}
выход:
2415 4
/*Function return size of string and convert signed *
*integer to ascii value and store them in array of *
*character with NULL at the end of the array */
int itoa(int value,char *ptr)
{
int count=0,temp;
if(ptr==NULL)
return 0;
if(value==0)
{
*ptr='0';
return 1;
}
if(value<0)
{
value*=(-1);
*ptr++='-';
count++;
}
for(temp=value;temp>0;temp/=10,ptr++);
*ptr='\0';
for(temp=value;temp>0;temp/=10)
{
*--ptr=temp%10+'0';
count++;
}
return count;
}
Если вы хотите вывести свою структуру в файл, нет необходимости предварительно преобразовывать какое-либо значение. Вы можете просто использовать спецификацию формата printf, чтобы указать, как вывести ваши значения, и использовать любой из операторов семейства printf для вывода ваших данных.
Улучшенный ответ user714501 .
Включать:
#include <math.h> // log10, floor
#include <stdio.h> // sprintf
#include <stdlib.h> // abs
Создайте свой номер:
int num = 123;
Рассчитать длину:
size_t len;
if (abs(num)) { // if not zero
len = floor(log10(abs(num)) + 1); // taking 'round' numbers into account too
if (num < 0) len++; // add minus sign
} else { // if zero
len = 1;
}
Затем вы можете сохранить свою строку как локальную переменную:
char str[len];
sprintf(str, "%d", num);
// do stuff
или как указатель:
char *str = malloc(len * sizeof(char));
sprintf(str, "%d", num);
// do stuff
free(str);
Надеюсь, это поможет!
INT TO CHAR [пример полного кода]
#include <stdio.h>
int main()
{
char s[]="";
sprintf(s,"%d",368);
printf("%s",s);
}
И не нужно объявлять векторный размер s [].. круто гун?!:-)
ПРИМЕЧАНИЕ: не начинайте значение int с "0"
Использовать функцию itoa() для преобразования целого числа в строку
Например:
char msg[30];
int num = 10;
itoa(num,msg,10);