itoa function for GCC - c

itoa is not an ANSI-C standard therefore doesn't work for GCC
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];
}
Questions I have
static char buf[32]
Why use static? Can I delete that?
Why i=30?
Shouldn't it be 31? 0 to 31 for 32 bits.
For the for-loop, what is val /= base trying to do?
Inside the for-loop, what does val%base do? I know it's for remainder but how's that relate to here? What's the difference between val/base versus val%base?

1) as #Blastfurnace noted, the static is needed so that the buffer still exists when the function returns
2) i=30 because its the last used index, because the index 31 needs to be NULL (\0). because c works with Null-Terminated-Strings
3) removing the last digit. i.e: val = 12345, base = 10, val / base = 1234, 5 is removed
4) getting the current digit (right to left) , 12345 % 10 = 5 (its also the index of the char array representing the digits (very efficient)

1)static char buf[32]
why use static? can I delete that?
So it doesn't get reloaded everytime the routine is called. No, the routine needs it to store the ascii values to be output.
2)why i=30?
shouldn't be 31? 0 to 31 for 32 bits
Not sure, but 30 characters represents 120 bits, not 30.
3) for the for loop, what does val /=base trying to do?
It's reducing the base on each iteration so the remainder value (used as an index to the array) will be correct.
4)inside the for loop, what does val%base do? I know it's for remainder but how's that relate to here? what's the difference between val/base versus val%base?
It calculates the remainder as an index into buf, to select the correct ascii value. / returns the integer (rounded off) divide, not the remainder of that divide.
Value = (Value/divisor)*divisor + Value%divisor.
thanks

Related

Get a part of an integer in C

I came from python and it was easy to get the middle digit of an integer, for example, from 897 I want the 9:
>>> num = 897
>>> num2 = int(str(num)[1])
>>> num2
9
But how i can do this on C? It's so difficult to convert into string...
Getting a single digit as an int can be done mathematically:
int num = 897;
int dig1 = (num / 1 ) % 10;
int dig2 = (num / 10 ) % 10;
int dig3 = (num / 100 ) % 10;
Division by one on the first line is only for illustration of the concept: you divide by n-th power of ten, starting with 100 = 1.
You can try the modulus operator (%).
In your case
num = 897
lastDigit = num%10; // Which returns 7
lastDigit/= 10;
secondLastDigit = lastDigit%10; //Which returns 9
Do this using a while loop for as long as you want. EG.
while(num>0)
{
digit = num%10;
num/=10;
}
The closest approximation in C to the given Python fragment, and its str operator, is sprintf/snprintf:
int num = 897;
char numstr[30];
sprintf(numstr, "%d", num);
char num2 = numstr[1];
int num2n = num2 - '0';
printf("%d\n", num2n);
To guard against buffer overflow, it's safer to get in the habit of using snprintf rather than sprintf:
snprintf(numstr, sizeof(numstr), "%d", num);
Instead of sprintf and %d, some systems provide an itoa() function (the opposite of atoi) for converting integers to strings, but it's not standard. For more information about converting numbers to strings, see Converting int to string in C.
This is "harder" in C than it is in Python for a couple of reasons. Constructing strings from numbers typically involves calls to snprintf, which is both more flexible and more of a nuisance than just calling str(). You typically have to worry about how big the destination array (here numstr) needs to be; this difficulty stems from C's lack of a first-class string type. And C has no convenience method for converting back and forth between digit characters and their values, so C programmers get used to adding and subtracting the constant '0' (or, if they like to make more work for themselves, 48).
(And the other part of the difficulty stems, I guess, from practicality. C was originally designed for writing operating systems and text editors and system utilities and things. How often do you need the middle digit of a number, anyway?)

How do I populate an array with the digits of a given integer in C? [duplicate]

This question already has answers here:
convert an integer number into an array
(8 answers)
Closed 7 years ago.
So lets say you have an integer in your code declared
int my_num = 967892;
and you have an array
int a[6];
How would you put that integer into the array so it looks like this?
{ 9, 6, 7, 8, 9, 2 }
Perhaps like this:
const unsigned char digits[] = { 9, 6, 7, 8, 9, 2 };
but there are many things that are unclear with your question, of course.
If you want to do this at runtime, as your comment now makes me believe, you need more code of course. Also, it will be tricky to make the array "fit" the number exactly, since that requires runtime-sizing of the array.
The core operation is % 10, which when applied to a number results in the rightmost digit (the "ones" digit).
You can do this by getting each digit and putting it into an array. Kudos to #unwind for thinking of using unsigned int because digits don't have signs. I didn't think of that.
DISClAIMER: this code is untested but would, theoretically, if I haven't made any mistakes that the community will catch, accomplish your task.
NOTE: This program is implementation-defined when theNum is negative. See this SO question for more info on what that means. Also, the accepted answer in the question of which this post is a duplicate has shorter code than this but uses log10 which (according to commenters) could be inaccurate.
//given theNum as the number
int tmp = theNum;
int magnitude = 0;
//if you keep dividing by 10, you will eventually reach 0 (integer division)
//and that will be the magnitude of the number + 1 (x * 10^n-1)
for (; tmp > 0; magnitude++){ //you could use a while loop but this is more compact
tmp /= 10;
}
//the number of digits is equal to the magnitude + 1 and they have no sign
unsigned int digits[magnitude];
//go backwards from the magnitude to 0 taking digits as you go
for (int i = magnitude - 1; i > 0; i--){
//get the last digit (because modular arithmetic gives the remainder)
int digit = theNum % 10;
digits[i] = digit; //record digit
theNum /= 10; //remove last digit
}
If this shall be done dynamically:
Determine the number of digits as N.
Allocate an array large enough (>=N) to hold the digits.
Loop N times chopping of the digits and storing them in the array allocated under 2.
The least significant digit is num % 10
The next digit can be found by num/=10;
This works for positive numbers, but is implementation defined for negative
I assume you want to achieve something like this:
int arr[SOME_SIZE];
int len = int_to_array(arr,421);
assert(len == 3);
assert(arr[0] == 4);
assert(arr[1] == 2);
assert(arr[1] == 1);
Since this is probably a homework problem, I won't give the full answer, but you'll want a loop, and you'll want a way to get the last decimal digit from an int, and an int with the last digit removed.
So here's a hint:
421 / 10 == 42
421 % 10 == 1
If you want to create an array of the right length, there are various approaches:
you could loop through twice; once to count digits (then create the array); once again to populate
you could populate an array that's bigger than you need, then create a new array and copy in as many members as necessary
you could populate an array that's bigger than you need, then use realloc() or similar (a luxury we didn't used to have!)

Converting a number to string with multiple arguments

I want to convert a number x of a base n to a string and store it in str. str has the max size of max. In this program I don't want to use any library functions. If I reach the maximum size of the array, the function should return false and the array contents should be undefined.
The prototype of the function looks like this:
bool num2str(int x, char *str, unsigned n, unsigned max);
How would I go about making this work? I'm having trouble understanding the algorithm behind it.
I also need to check the value of n, but I already did that:
bool num2str(int x, char *str, unsigned n, unsigned max)
{
assert(n >= 2 && n <= 36);
return true;
}
But that's all I could do. Please help.
Let's take a number in base 10: 123456. Now let's repeatedly apply a modulus and an integer division using the number and base 10:
123456 mod 10 = 6
123456 div 10 = 12345
12345 mod 10 = 5
12345 div 10 = 1234
As you can see, modulus by base extracts the last digit, while integer division by base shifts the number on digit to the right. You can do the same for any base. Hope this hint is enough.

How can I iterate through each digit in a 3 digit number in C?

Length is always 3, examples:
000
056
999
How can I get the number so I can use the value of the single digit in an array?
Would it be easier to convert to an char, loop through it and convert back to int when needed?
To get the decimal digit at position p of an integer i you would do this:
(i / pow(p, 10)) % 10;
So to loop from the last digit to the first digit, you would do this:
int n = 56; // 056
int digit;
while(n) {
digit = n % 10;
n /= 10;
// Do something with digit
}
Easy to modify to do it exactly 3 times.
As Austin says, you can easily find answers on Google. But it basically involves mod-by-10, then divide-by-ten. Assuming integers.

How to split up a two-digit number in C

Let's say I have a number like 21 and I want to split it up so that I get the numbers 2 and 1.
To get 1, I could do 1 mod 10. So basically, the last digit can be found out by using mod 10.
To get 2, I could do (21 - (1 mod 10))/10.
The above techniques will work with any 2-digit number.
However, let me add a further constraint, that mod can only be used with powers of 2. Then the above method can't be used.
What can be done then?
2 == 23 / 10
3 == 23 - (23 / 10) * 10
To get 2 you can just do
int x = 23 / 10;
remember that integer division drops the fractional portion (as it can't be represented in an integer).
Modulus division (and regular division) can be used for any power, not just powers of two. Also a power of two is not the same thing as a two digit number.
To split up a three digit number
int first = 234/100;
int second = (234/10)-first*10;
int third = (234/1)-first*100-second*10;
with a little work, it could also look like
int processed = 0;
int first = 234/100-processed;
processed = processed + first;
processed = processed * 10;
int second = 234/10-processed;
processed = processed + second;
processed = processed * 10;
... and so on ...
If you put a little more into it, you can write it up as a loop quite easily.
what about
x%10 for the second digit and
x/10 for the first?

Resources