在C语言中,如何将unsigned long 值转换为字符串(char*)并保持我的源代码可移植或只是重新编译它以在其他平台上工作(不重写代码?
例如,如果我有sprintf(buffer, format, value),我如何以平台无关的方式确定缓冲区的大小?
jfs*_*jfs 26
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);
Run Code Online (Sandbox Code Playgroud)
标准的做法是用sprintf(buffer, "%lu", value);写的字符串代表value到buffer.但是,溢出是一个潜在的问题,因为sprintf很快(并且在不知不觉中)写入缓冲区的末尾.
这实际上是sprintf的一大弱点,通过使用流而不是缓冲区在C++中部分修复.通常的"答案"是分配一个非常大的缓冲区,不太可能溢出,让sprintf输出到那个,然后使用strlen来确定生成的实际字符串长度,calloc缓冲区(那个大小+ 1)并将字符串复制到那个.
某些库提供snprintf了一种替代方法,允许您指定最大缓冲区大小.
小智 5
你可以编写一个从unsigned 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);
}
Run Code Online (Sandbox Code Playgroud)