我有一小段代码可以将整数转换为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不是正确的事情,因为最初我想要保护免受缓冲区溢出,但由于整数的大小已知,我认为它是无用的。我仍然想知道这里最好的做法是什么。
答案 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);