如何安全快速地从int中提取数字?

时间:2010-08-31 04:13:57

标签: c++ c digits

我们目前有一些代码从int中提取数字,但我需要将其转换为没有snprintf的平台,我担心缓冲区溢出。我已经开始编写自己的便携式(和优化的)snprintf但我被告知在这里询问以防有人有更好的想法。

int extract_op(int instruction)
{ 
    char buffer[OP_LEN+1];
    snprintf(buffer, sizeof(buffer), "%0*u", OP_LEN, instruction);
    return (buffer[1] - 48) * 10 + buffer[0] - 48;
}

我们正在使用C字符串,因为速度非常重要。

5 个答案:

答案 0 :(得分:7)

为此,您无需将instruction形成为字符数组;你只需要保留“两位数”,如下所示:

int extract_op(unsigned int instruction)
{
    int first = 0;
    int second = 0;
    while(instruction) {
        second = first;
        first = instruction % 10;
        instruction /= 10;
    }
    return first + 10 * second;
}

我认为return中的表达式是错误的,但它确实模仿了你正在做的事情: second 数字的十倍,加上第一个。

我怀疑速度可能比现在的速度更好,但当然,这取决于您在特定平台和编译器上进行测量。

答案 1 :(得分:2)

使用sprintf应该没问题。 sizeof type * 3 * CHAR_BIT / 8 + 2是一个足够大的缓冲区,用于打印type类型的整数。如果假设CHAR_BIT为8或者您只关心无符号格式,则可以简化此表达式。它背后的基本思想是每个字节最多以十进制(或八进制)形式提供3位数字,并且您需要空格用于符号和空终止。

答案 2 :(得分:1)

到目前为止,有一个答案可以交换最后两位数字和一个交换前两位数字的答案...它看起来像"%0*u", OP_LEN强制输出到特定宽度,并且提取的数字的重要性是预先确定的OP_LEN

假设OP_LEN是一个宏,我们可以得到10 ^(OP_LEN-2)

#define DIVISOR ( (int) ( 1.e ## OP_LEN * 0.01 ) )

然后,类似于@zneak的回答,

int extract_op( int instruction )
{
    instruction /= DIVISOR;
    int tens = (instruction / 10) % 10;
    int units = instruction % 10;
    return units * 10 + tens;
}

#undef DIVISOR

答案 3 :(得分:0)

你可以存储你进入阵列的数字。 这一个是ALEX解释的代码。 我在这里添加一些变量。

int a[5];

int extract_op(unsigned int instruction)
{
int i=0;    
int first = 0;
    int second = 0;
    while(instruction) {
        second = first;
        first = instruction % 10;
        instruction /= 10;
    }
    a[i]=first;
}

这适用于所有整数最多5位数。 但是如果你想采用动态数组,那么你可以使用链接列表

答案 4 :(得分:0)

也适用于0和< 0。

int extract_op( int instruction )
{
  int numd = 1;
  while( instruction /= 10 )
    ++numd;
  return numd;
}