如何提高缓冲区大小测定printfing各种整数类型? [英] How to improve buffer size determination for printfing various integer types?

查看:289
本文介绍了如何提高缓冲区大小测定printfing各种整数类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当一个整数转换为文本,通常我创建的的缓冲区来用sprintf()持有任何可能的结果。

When converting an integer to text, typically I create a big buffer to use with sprintf() to hold any potential result.

char BigBuffer[50];
sprintf(BugBuffer, "%d", SomeInt);

我想更多的空间和高效便携肯定,所以不是 50 ,找到替代:结果
(的sizeof(INTEGER_TYPE)* * CHAR_BIT 0.302)+ 3

// 0.0302 about log10(2)
#define USHORT_DECIMAL_BUFN ((size_t) (sizeof(unsigned short)*CHAR_BIT*0.302) + 3)
#define INT_DECIMAL_BUFN    ((size_t) (sizeof(int)           *CHAR_BIT*0.302) + 3)
#define INTMAX_DECIMAL_BUFN ((size_t) (sizeof(intmax_t)      *CHAR_BIT*0.302) + 3)

int main() {
    char usbuffer[USHORT_DECIMAL_BUFN];
    sprintf(usbuffer, "%hu", USHRT_MAX);
    printf("Size:%zu Len:%zu %s\n", sizeof(usbuffer), strlen(usbuffer), usbuffer);

    char ibuffer[INT_DECIMAL_BUFN];
    sprintf(ibuffer, "%d", INT_MIN);
    printf("Size:%zu Len:%zu %s\n", sizeof(ibuffer), strlen(ibuffer), ibuffer);

    char imbuffer[INTMAX_DECIMAL_BUFN];
    sprintf(imbuffer, "%" PRIdMAX, INTMAX_MIN);
    printf("Size:%zu Len:%zu %s\n", sizeof(imbuffer), strlen(imbuffer), imbuffer);
    return 0;
}

Size:7 Len:5 65535
Size:12 Len:11 -2147483648
Size:22 Len:20 -9223372036854775808

所以,在问题是:结果
1是否与替代式的问题吗?结果
2有什么更好的解决办法? - 因为这选择是一点点浪费,看起来过于复杂

So the questions are:
1 Is there a problem with the alternative equation?
2 What better solution? - as this alternative is a tad wasteful and looks overly complicated.

解答提供周到3的方法:结果
1使用缓冲区[最大尺寸类型] (选择应答)结果
2 asprintf()结果
3 的snprintf()

Answers provide 3 thoughtful approaches:
1 Use buffer[max size for type] (Answer selected)
2 asprintf()
3 snprintf()

1使用公式编译时的最大缓冲区大小(的sizeof(INTEGER_TYPE)* * CHAR_BIT 0.302)+ 3 是不破,也没有得到改善。 locale.h文件> 进行了研究由@paddy和受影响没有区域设置整数转换的建议%D%X%U%I 1所述的影响。它被发现略有改善,可以对方程作出如果类型已知符号或无符号(下同)。关于更加保守@paddy谨慎是很好的建议。

1 The compile time max buffer size using equation (sizeof(integer_type)*CHAR_BIT*0.302) + 3 was not broken nor improved. The impact of <locale.h> was researched as suggested by @paddy and no locale settings affected integer conversions %d %x %u %i. It was found a slight improvement may be made to the equation if the type is known to be signed or unsigned (below). @paddy caution about "more conservative" is good advice.

2 asprintf()的确是一个不错的通用解决方案,但不便于携带。也许在-C11帖子?

2 asprintf() is really a good all-purpose solution, but not portable. Maybe in post-C11?

3 的snprintf(),虽然标准的,就知道一贯执行的问题时,提供的缓冲区不够大。这意味着与过大的缓冲区调用它,然后生成一个右大小的缓冲区。 @jxh建议一个线程安全全球临时缓冲区,以形成具有一个本地合适大小的缓冲器中的答案。这种新方法值得考虑,我可以使用,但原来的问题更多地集中在之前确定 S(N)的printf()调用一个保守的缓冲区大小。

3 snprintf(), although standard, has known consistent implementation issues when the supplied buffer is undersized. This implies calling it with an over-sized buffer and then generating a right-size buffer. @jxh suggested a thread safe global scratch buffer to form the answer with a local right-sized buffer. This novel approach deserves consideration which I may use, but the original question focused more on determining before the s(n)printf() call a conservative buffer size.

签订((的sizeof(INTEGER_TYPE)* CHAR_BIT-1)* 0.302)+ 3 结果
无符号(的sizeof(INTEGER_TYPE)* * CHAR_BIT 0.302)+ 2 结果
*93分之28来代替中使用* 0.302

推荐答案

这对我来说很好。你四舍五入小数点起来,增加了一个额外字符负号和零和一个额外的好措施。我不认为你需要担心出来的数字更长,如果你不使用的功能&LT; locale.h文件方式&gt;

It looks good to me. You've rounded the decimal up, added an extra character for the negative sign and the null, and one extra for good measure. I don't think you need to worry about numbers coming out longer if you're not using features from <locale.h>.

我的问题是关于你打算用这些做什么。你只需构造它们在栈上,或者是你把其中很多到内存?

My question is about what you intend to do with these. Are you simply constructing them on the stack, or are you putting lots of them into memory?

通过堆栈上的临时数组,你通常不会因为它是不太可能影响缓存性能大惊小怪几个字节。这当然是不会吹出来的你的记忆。

With temporary arrays on the stack, you normally wouldn't fuss over a few bytes as it's unlikely to affect cache performance. It certainly isn't going to blow out your memory.

如果您打算存储大量的这些,你可能要考虑池。然而,你需要考虑池的内存开销。一池的本质意味着你保留更多的内存比你要使用的。如果编译64位,你的指针是8个字节。如果大部分的数字是4个字符长,那么8个字节的指针加上每个号码5字节的存储空间会否定任何可能的好处,也许除了64位数字。

If you are planning to store lots of these, you may want to consider pooling. However, you would need to consider the memory overhead of pooling. The very nature of a pool means you reserve more memory than you are going to use. And if compiling 64-bit, your pointers are 8 bytes. If most of your numbers are 4 characters long, then the 8-byte pointer plus the 5 bytes of storage for each number would negate any possible benefits, except perhaps for 64-bit numbers.

这只是我的思维过程。在我看来,你已经修剪整齐的脂肪。我倾向于比较保守,但可能是主要的偏执狂。保持简单,通常要走的路,和过度的思维可能是一个陷阱。如果你有过思考,然后考虑的原因,并决定是否它是实际上需要那么多的想法。

These are just my thought processes. It seems to me that you have trimmed the fat nicely. I tend to be a little more conservative, but that may be mostly paranoia. Keeping it simple is usually the way to go, and over-thinking can be a trap. If you are over-thinking then consider the reasons why, and decide whether it's a problem that actually requires that much thought.

这篇关于如何提高缓冲区大小测定printfing各种整数类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆