在C语言中,如何将无符号长值转换为字符串(char *),并保持源代码可移植性,或者只是重新编译它以在其他平台上工作(而不重写代码)?
例如,如果我有sprintf(buffer, format, value),如何用平台无关的方式确定缓冲区的大小?
发布于 2010-04-25 20:08:46
const int n = snprintf(NULL, 0, "%lu", ulong_value);
assert(n > 0);
char buf[n+1];
int c = snprintf(buf, n+1, "%lu", ulong_value);
assert(buf[n] == '\0');
assert(c == n);发布于 2010-04-25 20:08:48
标准的方法是使用sprintf(buffer, "%lu", value);将value的字符串代表写到buffer。但是,溢出是一个潜在的问题,因为sprintf会很高兴(而且不知情地)在缓冲区的末尾写入。
这实际上是sprintf的一个很大的弱点,它在C++中通过使用流而不是缓冲区来部分修复。通常的“答案”是分配一个不太可能溢出的非常慷慨的缓冲区,让sprintf输出到该缓冲区,然后使用strlen来确定实际产生的字符串长度,calloc (该大小+ 1)的缓冲区并将字符串复制到该缓冲区。
本站详细讨论了这一问题和相关问题。
有些库提供snprintf作为替代,允许您指定最大缓冲区大小。
发布于 2013-03-03 02:50:31
您可以编写一个函数,该函数可以将未签名的long转换为str,类似于ltostr库函数。
char *ultostr(unsigned long value, char *ptr, int base)
{
unsigned long t = 0, res = 0;
unsigned long tmp = value;
int count = 0;
if (NULL == ptr)
{
return NULL;
}
if (tmp == 0)
{
count++;
}
while(tmp > 0)
{
tmp = tmp/base;
count++;
}
ptr += count;
*ptr = '\0';
do
{
res = value - base * (t = value / base);
if (res < 10)
{
* -- ptr = '0' + res;
}
else if ((res >= 10) && (res < 16))
{
* --ptr = 'A' - 10 + res;
}
} while ((value = t) != 0);
return(ptr);
}您可以参考我的博客这里,它用示例解释了实现和使用。
https://stackoverflow.com/questions/2709713
复制相似问题