Convert integer to string without access to libraries
Solution 1
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];
}
if(n == 0)
{
buffer[0] = '0';
buffer[1] = '\0';
}
printf(buffer);
Solution 2
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];
}
Solution 3
The algorithm is easy to see in English.
Given an integer, e.g. 123
divide by 10 => 123/10. Yielding, result = 12 and remainder = 3
add 30h to 3 and push on stack (adding 30h will convert 3 to ASCII representation)
repeat step 1 until result < 10
add 30h to result and store on stack
the stack contains the number in order of | 1 | 2 | 3 | ...
Solution 4
Convert integer to string without access to libraries
Convert the least significant digit to a character first and then proceed to more significant digits.
Normally I'd shift the resulting string into place, yet recursion allows skipping that step with some tight code.
Using neg_a
in myitoa_helper()
avoids undefined behavior with INT_MIN
.
// Return character one past end of character digits.
static char *myitoa_helper(char *dest, int neg_a) {
if (neg_a <= -10) {
dest = myitoa_helper(dest, neg_a / 10);
}
*dest = (char) ('0' - neg_a % 10);
return dest + 1;
}
char *myitoa(char *dest, int a) {
if (a >= 0) {
*myitoa_helper(dest, -a) = '\0';
} else {
*dest = '-';
*myitoa_helper(dest + 1, a) = '\0';
}
return dest;
}
void myitoa_test(int a) {
char s[100];
memset(s, 'x', sizeof s);
printf("%11d <%s>\n", a, myitoa(s, a));
}
Test code & output
#include "limits.h"
#include "stdio.h"
int main(void) {
const int a[] = {INT_MIN, INT_MIN + 1, -42, -1, 0, 1, 2, 9, 10, 99, 100,
INT_MAX - 1, INT_MAX};
for (unsigned i = 0; i < sizeof a / sizeof a[0]; i++) {
myitoa_test(a[i]);
}
return 0;
}
-2147483648 <-2147483648>
-2147483647 <-2147483647>
-42 <-42>
-1 <-1>
0 <0>
1 <1>
2 <2>
9 <9>
10 <10>
99 <99>
100 <100>
2147483646 <2147483646>
2147483647 <2147483647>
Solution 5
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.
Related videos on Youtube
Nick Sinas
I have experience developing in Assembly Embedded C C++ C# Objective-C Swift Python And a tiny bit of HTML/CSS I am currently a C# and iOS developer at Metova
Updated on October 23, 2020Comments
-
Nick Sinas over 3 years
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?
-
pmg over 13 yearshomework? What would you do to write an integer in base 7? The computer has to do the same (in base 10)
-
James McNellis over 13 years
atoi()
is even more fun because you have to handle leading whitespace, the unary plus or minus, and both positive and negative overflow (among other things).
-
-
James McNellis over 13 yearsThis does not handle negative numbers and
MaxDigitCount
needs to beMaxDigitCountPlusTwo
to account for the unary minus and the null terminator. -
gabac over 13 yearswhy would itoa handle floating point numbers? itoa is Integer to ASCII
-
eyalm over 13 yearsI 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.
-
R.. GitHub STOP HELPING ICE over 13 yearsWhy 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.
-
nategoose over 13 yearsI 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.
-
Manoj R over 13 yearsAbout to suggest the same thing. Put in string and reverse string.
-
schot over 13 yearsThis fails to handle
INT_MIN
correctly on two's complement machines. -
unwind over 13 yearsIt'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.
-
Lightness Races in Orbit about 11 years@R. It is not your job to "undo" other peoples' right to vote.
-
R.. GitHub STOP HELPING ICE about 11 yearsI don't think it's unreasonable to vote based on a feeling that the current score is either too high or too low; naively, I would expect lots of people do that. Of course this seems like a discussion more appropriate for meta, so if you think it merits further discussion, maybe open a question there..?
-
Mike about 11 yearsHow to handle the situation when base equals 16?
-
nategoose about 11 years@R: In reply to your first post stating that the answer was "not so good", that was intentional because I highly suspected that the question was someone's homework. The intent was to provide enough guidance for them to implement it themselves, without doing it for them. Thanks for the neutralizing vote.
-
Spidey almost 11 yearsI think you meant
pru
where you've writtenfmtu
, right? Also, those names are nasty. Are they meant to be understood as 'print unsigned', 'print integer' and 'format unsigned'? Also, this supposes a fixed-length string or memory buffer, since it's not handling the NUL character, and also that the buffer is long enought to be traversed backwards. You should note all this restrictions as a comment or more semantical identifiers in your code. -
Nicholas Wilson about 10 yearsAdding
'0'
is tying the code to ASCII - you're assuming that '0'..'9' are laid out in order for you. Adding 0x30 produces ASCII output regardless of the compiler's codeset. Adding '0' produces the same output if the compiler's codeset is ASCII, and potentially garbled output otherwise. Having said that, I'd replace my compiler if it didn't use ASCII values for character constants! -
MickLH almost 10 years@LightnessRacesinOrbit It's every users job to use their own vote effectively to promote useful information while burying garbage.
-
Lightness Races in Orbit almost 10 years@MickLH: To promote what they consider to be useful information while burying what they consider to be garbage. When you vote solely to undo someone else's vote, you are in wilful counteraction to the purpose of the voting system that you have just described.
-
igauravsehrawat over 9 years@Mike best way without complicating things will be to convert it to decimal & do the same .
-
wonder.mice almost 9 yearsThis implementation will fail when val is 0 (zero).
-
wonder.mice almost 9 yearsThis implementation also will fail when num is 0 (zero).
-
wonder.mice almost 9 yearsThis implementation also will fail when n is 0 (zero).
-
user694733 almost 7 years@NicholasWilson C standard requires that number digits are laid out in order for both; source and execution character sets.
-
Haggra about 6 yearsSome comments to explain what's going on could make it easier to understand.
-
Goku over 5 yearswhats going on here: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]; }
-
gabac over 5 years@Goku it reverses the buffer... it's been a while since looking at this :)
-
chux - Reinstate Monica about 5 years
*--eob = x%10;
is wrong.-x
potential UB, no null character for a string. -
chux - Reinstate Monica about 5 years
-n
is UB whenn == INT_MIN
. -
Cristian about 4 yearsI really like your answer but I think it could be improved with a few tweaks. For example
char tochar(unsigned short from)
can be optimised:inline char tochar(unsigned char from) { if (from > 9) return '0'; return '0' + from; }
The edge case could be removed in this particular example since you are sure you will always pass totochar
numbers from 0 to 9. -
Beyondo about 4 years@Cristian That's such an old answer of mine, so believe when I say that I've thought exactly the same thing the moment I saw my answer now! Haha.. Now I've edited it including some other things too since it mentioned "no libraries" and looks like I had blindly used
calloc
here 2 years ago which obviously needs a library as I can recall~ So, thank you. now it is even better. :) -
Ekrem Dinçel over 3 yearsThis is clever. I liked it.
-
mercury0114 over 3 yearsIt also does not handle negative numbers, but props for being short.