2

我有一小段代码可以将整数转换为 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 不是正确的做法,因为最初我想防止缓冲区溢出,但由于整数的大小是已知的,我认为它是无用的。我仍然想知道这里的最佳做法是什么。

4

6 回答 6

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);
于 2011-10-17T12:05:51.957 回答
2

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

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

于 2011-10-17T12:16:32.837 回答
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()无论如何都在这里调用(不便宜),删除它可能不是一个很好的胜利。

于 2011-10-17T12:06:33.053 回答
0

您可以在临时缓冲区中 sprintf,然后分配合适的大小(返回 sprintf),然后将临时复制到缓冲区中。

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); 
于 2011-10-17T12:06:27.353 回答
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;
}
于 2012-11-19T15:52:53.410 回答
0

解决此问题的一个简单、可移植(跨各种位数、平台和 CPU)的解决方案是:

int tmp_integer = /*read as integer*/
const size_t len = 4 * sizeof(int);
char tmp_string[len];
snprintf(tmp_string, len, "%d", tmp_integer);
于 2018-06-13T20:50:37.553 回答