计算作为文本写入的数字长度的最简单/最优雅的方法是什么?

CsT*_*mas 3 c++ fixed-length-record

给定最大可能值,如何简单地表示以十进制形式将此数字写为文本所需的空间?

真正的任务:pid_t使用Linux上的gcc 记录固定长度的进程ids().在std::setw()iomanipulator中使用编译时表达式会很好.

我发现linux/threads.h头包含一个PID_MAX值,该值具有分配给进程的最大pid.所以有

#define LENGTH(t) sizeof(#t)-1
Run Code Online (Sandbox Code Playgroud)

LENGTH(PID_MAX)将是一个编译时表达式,但不幸的是这个数字是以hexa定义的:

#define PID_MAX 0x8000
Run Code Online (Sandbox Code Playgroud)

我目前最好的解决方案有点奇怪

static_cast<int>( ::floor( ::log(PID_MAX)/::log(10) + 1 ) );
Run Code Online (Sandbox Code Playgroud)

但这是计算运行时并使用math.h中的函数

Mat*_*ice 14

您可以使用一些模板元编程来完成它:

//NunLength_interal does the actual calculation. 
template <unsigned num>
struct NumLength_internal
{ enum { value = 1 + NumLength_internal<num/10>::value }; };

template <>
struct NumLength_internal<0>
{ enum { value = 0 }; };

//NumLength is a wrapper to handle zero. For zero we want to return
//a length of one as a special case.
template <unsigned num>
struct NumLength
{ enum { value = NumLength_internal<num>::value };};

template <>
struct NumLength<0>
{ enum { value = 1 }; };
Run Code Online (Sandbox Code Playgroud)

这应该适用于任何事情.例如:

cout << NumLength<0>::value      << endl; // writes: 1
cout << NumLength<5>::value      << endl; // writes: 1
cout << NumLength<10>::value     << endl; // writes: 2
cout << NumLength<123>::value    << endl; // writes: 3
cout << NumLength<0x8000>::value << endl; // writes: 5
Run Code Online (Sandbox Code Playgroud)

这都是在编译时处理的.

编辑:我添加了另一个图层来处理传入的数字为零的情况.