views:

213

answers:

9

I recently read a sample job interview question:

Write a function to convert an integer to a string. Assume you do not have access to library functions i.e., itoa(), etc...

How would you go about this?

A: 

I would keep in mind that all of the digit characters are in increasing order within the ASCII character set and do not have other characters between them.

I would also use the / and the% operators repeatedly.

How I would go about getting the memory for the string would depend on information you have not given.

nategoose
Why the downvotes? The relationship between digit values is not ASCII-specific. It's required by the C standard. This answer is not so good, but I think it's intentionally vague since the question was homework. +1 to compensate for ridiculous downvotes.
R..
I suspect the downvotes because I didn't write any code. I didn't write any code because it seemed like either a _homework_ question or the type of question which anyone interviewing for a job as a _C_ programmer should have been able to answer.
nategoose
+1  A: 

Assuming it is in decimal, then like this:

   int num = ...;
   char res[MaxDigitCount];
   int len = 0;
   for(; num > 0; ++len)
   {
      res[len] = num%10+'0';
      num/=10; 
   }
   res[len] = 0; //null-terminating

   //now we need to reverse res
   for(int i = 0; i < len/2; ++i)
   {
       char c = res[i]; res[i] = res[len-i-1]; res[len-i-1] = c;
   }   
Armen Tsirunyan
This does not handle negative numbers and `MaxDigitCount` needs to be `MaxDigitCountPlusTwo` to account for the unary minus and the null terminator.
James McNellis
+3  A: 

fast stab at it: (edited to handle negative numbers)

int n = INT_MIN;
char buffer[50];
int i = 0;

bool isNeg = n<0;

unsigned int n1 = isNeg ? -n : n;

while(n1!=0)
{
    buffer[i++] = n1%10+'0';
    n1=n1/10;
}

if(isNeg)
    buffer[i++] = '-';

buffer[i] = '\0';

for(int t = 0; t < i/2; t++)
{
    buffer[t] ^= buffer[i-t-1];
    buffer[i-t-1] ^= buffer[t];
    buffer[t] ^= buffer[i-t-1];
}

printf(buffer);
John Boker
About to suggest the same thing. Put in string and reverse string.
Manoj R
This fails to handle `INT_MIN` correctly on two's complement machines.
schot
@schot it should work now
John Boker
A: 

An implementation of itoa() function seems like an easy task but actually you have to take care of many aspects that are related on your exact needs. I guess that in the interview you are expected to give some details about your way to the solution rather than copying a solution that can be found in Google (http://en.wikipedia.org/wiki/Itoa)

Here are some questions you may want to ask yourself or the interviewer:

  • Where should the string be located (malloced? passed by the user? static variable?)
  • Should I support signed numbers?
  • Should i support floating point?
  • Should I support other bases rather then 10?
  • Do we need any input checking?
  • Is the output string limited in legth?

And so on.

eyalm
why would itoa handle floating point numbers? itoa is Integer to ASCII
John Boker
I just wanted to make a point. In an interview, the questions you raise and your way to the solutions are important just like the code. The code of-course should be perfect.
eyalm
A: 

Here's a simple approach, but I suspect if you turn this in as-is without understanding and paraphrasing it, your teacher will know you just copied off the net:

char *pru(unsigned x, char *eob)
{
    do { *--eob = x%10; } while (x/=10);
    return eob;
}

char *pri(int x, char *eob)
{
    eob = fmtu(x<0?-x:x, eob);
    if (x<0) *--eob='-';
    return eob;
}

Various improvements are possible, especially if you want to efficiently support larger-than-word integer sizes up to intmax_t. I'll leave it to you to figure out the way these functions are intended to be called.

R..
+1  A: 

The algorithm is easy to see in English.

Given an integer, e.g. 123

  1. divide by 10 => 123/10. Yielding, result = 12 and remainder = 3

  2. add 30h to 3 and push on stack (adding 30h will convert 3 to ASCII representation)

  3. repeat step 1 until result < 10

  4. add 30h to result and store on stack

  5. the stack contains the number in order of | 1 | 2 | 3 | ...

dnbwise
It's way better to add '0', rather than magical hex constants that happen to be correct in a common encoding. No need to tie code to ASCII when that's not necessary.
unwind
A: 

Just check my light and nice answer here.

ring0
A: 

A look on the web for itoa implementation will give you good examples. Here is one, avoiding to reverse the string at the end. It relies on a static buffer, so take care if you reuse it for different values.

char* itoa(int val, int base){

    static char buf[32] = {0};

    int i = 30;

    for(; val && i ; --i, val /= base)

        buf[i] = "0123456789abcdef"[val % base];

    return &buf[i+1];

}
Benoit Thiery
A: 

Slightly longer than the solution:

static char*
itoa(int n, char s[])
{
    int i, sign;

    if ((sign = n) < 0)  
        n = -n;        

    i = 0;

    do 
    {      
        s[i++] = n % 10 + '0';  
    } while ((n /= 10) > 0);   

    if (sign < 0)
        s[i++] = '-';

    s[i] = '\0';
    reverse(s);

    return s;
} 

Reverse:

int strlen(const char* str)
{
   int i = 0;
   while (str != '\0')
   {
       i++;
       str++;
   }

   return i;
}

static void
reverse(char s[])
{
    int i, j;
    char c;

    for (i = 0, j = strlen(s)-1; i<j; i++, j--) {
        c = s[i];
        s[i] = s[j];
        s[j] = c;
    }
}

And although the decision davolno long here are some useful features for beginners. I hope you will be helpful.

shk