如何在C中将int转换为字符串?

use*_*999 191 c string integer

如何将int(整数)转换为字符串?我正在尝试创建一个函数,将a的数据struct转换为字符串以将其保存在文件中.

cni*_*tar 179

您可以使用sprintf它,或者snprintf如果您拥有它:

char str[ENOUGH];
sprintf(str, "%d", 42);
Run Code Online (Sandbox Code Playgroud)

str可以使用以下公式计算字符数(加上终止字符):

(int)((ceil(log10(num))+1)*sizeof(char))
Run Code Online (Sandbox Code Playgroud)

  • 或者你可以在编译时计算它:`#define ENOUGH((CHAR_BIT*sizeof(int) - 1)/ 3 + 2)` (22认同)
  • 您不考虑减号和区域设置:千位分隔符和分组.请这样做:使用`int length = snprintf(NULL,0,"%d",42);`获取长度,然后为字符串分配`length + 1` chars. (22认同)
  • 为了确保tat`ENOUGH`足够我们可以通过`malloc(sizeof(char)*(int)log10(num))来实现它. (8认同)
  • Sic!...当然`(ceil(log10(num))+ 1)*sizeof(char)` (6认同)
  • @hauleth仍然+2而不是+1,即使是ceil:ceil(log(100))= 2.0,而不是3.所以+1表示精确的10次幂,另外+1表示终止null. (3认同)
  • @Hauleth甚至+2,考虑到`(int)log10(42)`是`1`. (2认同)
  • @ user2622016使用`NULL`缓冲区调用`snprintf`来确定所需的缓冲区大小是一个很好的技巧![这里是'printf`成员的比较](http://en.cppreference.com/w/c/io/fprintf),对于任何可能感兴趣的人. (2认同)

Ale*_*kin 79

编辑: 正如评论中指出的,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);
Run Code Online (Sandbox Code Playgroud)

如果要将结构输出到文件中,则无需事先转换任何值.您可以使用printf格式规范来指示如何输出值并使用printf系列中的任何运算符输出数据.

  • `itoa`不标准 - 参见http://stackoverflow.com/questions/190229/where-is-the-itoa-function-in-linux (19认同)
  • 为什么你将参数传递为 10 ? (5认同)
  • @PaulR 现在我不知道!感谢您的澄清。 (2认同)
  • itoa 在 C 语言中不可用(至少是 C99)。它在 C++ 中更可用 (2认同)

use*_*016 49

简短的回答是:

snprintf( str, size, "%d", x );
Run Code Online (Sandbox Code Playgroud)

时间越长:首先你需要找出足够的尺寸.snprintf如果你用NULL, 0第一个参数调用它会告诉你长度:

snprintf( NULL, 0, "%d", x );
Run Code Online (Sandbox Code Playgroud)

为null终止符分配一个字符.

int x = -42;
int length = snprintf( NULL, 0, "%d", x );
char* str = malloc( length + 1 );
snprintf( str, length + 1, "%d", x );
...
free(str);
Run Code Online (Sandbox Code Playgroud)

如果适用于每个格式字符串,那么您可以通过使用将float或double转换为字符串"%g",您可以将int转换为十六进制使用"%x",依此类推.

  • #include <stdio.h> #include <stdlib.h> (2认同)
  • 嘿,我知道这是非常旧的答案,但为什么在 malloc 中使用“+1”?是为了 '\0' 吗? (2认同)
  • 是的,+1 代表“\0”。snprintf 返回的长度不包括终止空字符,但在第二个参数中它期望长度包含终止空字符,因此长度 + 1。 (2认同)

Dav*_*ica 29

在查看了各种版本的itoa for gcc之后,我发现最灵活的版本能够处理二进制,十进制和十六进制的转换,正面和负面是http://www.strudel.org上的第四个版本. .uk/itoa /.虽然sprintf/ snprintf有优势,但除了十进制转换之外,它们不会处理负数.由于上面的链接是脱机的或不再活跃的,我在下面列出了他们的第4个版本:

/**
 * C++ version 0.4 char* style "itoa":
 * Written by Lukás Chmela
 * Released under GPLv3.
 */
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;
}
Run Code Online (Sandbox Code Playgroud)

  • 此外,这比sprintf快得多.转储大文件时可能很重要. (4认同)
  • @chux是的,编译器可以优化`sprintf(str,"%d",42);`作为附加两个const字符,但这就是理论.在实践中,人们不会sprintf const int,而上面的itoa几乎就像它得到的那样优化.至少你可以100%确定你不会得到普通sprintf降级的数量级.通过编译器版本和设置,可以看到您想到的任何反例. (3认同)
  • 最好提供一种方法来恢复输出长度。我已经在这里完成了:/sf/answers/3647800551/ +单元测试。 (2认同)

小智 8

这是旧的,但这是另一种方式.

#include <stdio.h>

#define atoa(x) #x

int main(int argc, char *argv[])
{
    char *string = atoa(1234567890);
    printf("%s\n", string);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

  • 仅适用于常量,不适用于变量. (28认同)

Vic*_*lea 7

如果您使用的是GCC,则可以使用GNU扩展名asprintf函数.

char* str;
asprintf (&str, "%i", 12313);
free(str);
Run Code Online (Sandbox Code Playgroud)


chu*_*ica 7

将任何内容转换为字符串应该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;
}
Run Code Online (Sandbox Code Playgroud)

方法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;
}
Run Code Online (Sandbox Code Playgroud)

[编辑]按照@Alter Mann的要求

(CHAR_BIT*sizeof(int_type)-1)*10/33+3至少是char将某些有符号整数类型编码为由可选的负号,数字和空字符组成的字符串所需的最大数量.

有符号整数中的非符号位数不超过CHAR_BIT*sizeof(int_type)-1.a n位二进制数的基数10表示占用n*log10(2) + 1数字. 10/33略多于log10(2).标志为char+1,空字符为+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));
}
Run Code Online (Sandbox Code Playgroud)

样本输出

0
1
-1
12345
2147483646
2147483647
-2147483647
-2147483648
Run Code Online (Sandbox Code Playgroud)

  • @Alter Mann`*10/33 + 3`在编辑的答案中解释. (2认同)

baz*_*baz 6

sprintf返回字节并添加一个空字节:

# include <stdio.h>
# include <string.h>

int main() {
    char buf[1024];
    int n = sprintf( buf, "%d", 2415);
    printf("%s %d\n", buf, n);
}

Run Code Online (Sandbox Code Playgroud)

输出:

# include <stdio.h>
# include <string.h>

int main() {
    char buf[1024];
    int n = sprintf( buf, "%d", 2415);
    printf("%s %d\n", buf, n);
}

Run Code Online (Sandbox Code Playgroud)