Question

We currently have some code to extract digits from an int, but I need to convert this to a platform without snprintf, and I am afraid of a buffer overrun. I have started to write my own portable (and optimized) snprintf but I was told to ask here in case someone had a better idea.

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;
}

We are using C strings because Speed is very important.

Was it helpful?

Solution

Using sprintf should be fine. sizeof type * 3 * CHAR_BIT / 8 + 2 is a sufficiently large buffer for printing an integer of type type. You can simplify this expression if you assume CHAR_BIT is 8 or if you only care about unsigned formats. The basic idea behind it is that each byte contributes at most 3 digits in decimal (or octal), and you need space for a sign and null termination.

OTHER TIPS

You don't need to form instruction into a character array for this purpose; you just need to keep "the two top digits", as follows:

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;
}

I think the expression in the return is wrong, but it does mimic what you're doing: ten times the second digit, plus the first one.

I suspect that speed might be even better than what you're getting now, but that's up to you to measure on your specific platform and compiler, of course.

So far there's one answer that swaps the last two digits and one that swaps the first two… it looks to me like "%0*u", OP_LEN is forcing the output to a particular width, and the significance of the extracted digits is predetermined by OP_LEN.

Assuming OP_LEN is a macro, we can get 10^(OP_LEN-2) with

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

Then, similar to @zneak's answer,

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

#undef DIVISOR

U can store the digit u are getting into array. THIS ONE WAS THE CODE EXPLAINED BY ALEX. here i am adding some variables.

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;
}

This is something will work for all integers will have max 5 digits. But still if u want to take dynamic array then u can use link list

should work also for 0 and <0.

int extract_op( int instruction )
{
  int numd = 1;
  while( instruction /= 10 )
    ++numd;
  return numd;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top