snprintf,用于C中的整数到字符串转换

时间:2011-10-17 11:58:28

标签: c c-strings

我有一小段代码可以将整数转换为c中的字符串。 该代码必须适用于32位和64位平台。

我在循环中解析参数,所以我需要malloc来创建缓冲区

int tmp_integer = /*read as integer*/
char* tmp_string = malloc(20* sizeof(char)); /*enough room for the biggest integer*/
snprintf(tmp_string, 20,"%d",tmp_integer); /*can I avoid using 20 here*/
a[i - 1] = tmp_string; /*save the parsed argument for final usage*/

我的问题是: 是否有任何方法可以使用snprintf使其更好,或者我应该回到sprintf。

我认为使用snprintf不是正确的事情,因为最初我想要保护免受缓冲区溢出,但由于整数的大小已知,我认为它是无用的。我仍然想知道这里最好的做法是什么。

6 个答案:

答案 0 :(得分:2)

如果动态分配内存,可以使用log10来计算字符串中所需的位置数:

int tmp_integer = /*read as integer*/ 
int signpadding = 0;
if tmpinteger < 0 then signpadding = 1;
int digitcount = (integer)floor(log10(abs(value)))+ 1 + signpadding;
char* tmp_string = malloc(digitcount * sizeof(char)); 
snprintf(tmp_string, digitcount,"%d",tmp_integer);

答案 1 :(得分:2)

在这种情况下你是对的。您知道您的号码不超过64位,而且您知道这意味着它的数量不会超过20位。因此,您实际上不需要使用snprintf

错误:您可以拥有的最大无符号64位数是18,446,744,073,709,551,615,即20位数。但是,每个字符串最后都有一个'\0'NUL)字符(因此以空字符结尾的字符串术语)。因此,您应该为数组分配 21 字节,而不是20。

答案 2 :(得分:1)

问题变成了神奇的“20”来自哪里。由于它是神奇的,它应该表示为符号常量,而不是代码中重复的整数字面值。使用符号常量还有让编译器为您执行错误检查的好处:

#define MAX_INTEGER_DIGITS (20)

int value = /* ... */
char* tmp_string = malloc(MAX_INTEGER_DIGITS);
snprintf(tmp_string, MAX_INTEGER_DIGITS, "%d", value);

(还要注意我是如何删除sizeof (char)的东西,因为它完全是多余的,并且(imo)非常混乱。)

从性能的角度来看,你可以取消字符串格式化程序的受保护变体,但是既然你在这里调用malloc()(不便宜),删除它可能不是一个好的胜利

答案 3 :(得分:0)

您可以在临时缓冲区中进行sprintf,然后分配好大小(返回sprintf),然后将temp复制到缓冲区中。

int tmp_integer = /*read as integer*/
static char tmp_string[20];
int size = sprintf(tmp_string,"%d",tmp_integer); 
char *myValueString = malloc((size+1)*sizeof(char));
a[i - 1] = strcpy(myValueString,tmp_string); 

答案 4 :(得分:0)

这是基于sum1stolemyname代码段转换它的另一种方法(可能不那么漂亮):

char *convert_int_to_string(int value)
{
    int digitcount;
    char * tmp_string;
    int increment = 2; // one for rounding, one for '\0' terminator
    if(value <0){
            increment += 1; // make room for sign 
    }
    if(0 == value){
            tmp_string = malloc(2* sizeof(char));
            sprintf(tmp_string, "%u", 0);
    }
    else{
            digitcount = (int)floor(log10((double)abs(value)))+ increment;
            tmp_string = malloc(digitcount * sizeof(char));
            sprintf(tmp_string, "%d", value);
    }
    return tmp_string;
}

答案 5 :(得分:0)

这个问题的简单,可移植(跨各种位,平台和cpus)解决方案是:

int tmp_integer = /*read as integer*/
const size_t len = 4 * sizeof(int);
char tmp_string[len];
snprintf(tmp_string, len, "%d", tmp_integer);