int atoi(char* s)
{
int i,n;
n=0;
for (i=0; (s[i]>='0') && (s[i]<='9'); i++)
n = 10 * n + (s[i] - '0');
return n;
}
In this code what is s[i]-'0' doing? Can anyone please explain the detailed working of this function?
Have a look at the table in the link below-
http://www.asciitable.com/
The table is called ASCII Table and it is one of the character-encoding schemes used to represent characters in the binary world.
You can see the decimal numbers 0-9 are represented by numbers 48-57 in the ASCII table. All digits(0-9) are stored as characters.
If your computer stores 48 for decimal number 0, 49 for decimal number 1, 50 for decimal number 2 and so-on.
Then, to convert a ASCII number into decimal number, you just need to subtract 48 from ASCII number.
For example,
48 - 48 => 0
49 - 48 => 1
50 - 48 => 2
.. and so-on
'0' also represents 48. It is a character form of number 48. That's why, the equation n = 10 * n + (s[i] - '0'); has '0'.
In this code what is s[i]-'0' doing?
In C, each character like '0', 'A', '+', ' ' is assigned a numeric value or code. C requires that the codes for '0', '1', '2' ... '9' are sequential but does not specify their values.
When code performs the below test, it knows that s[i] has a value within codes '0' and '9'. Since these codes are sequential, the only values s[i] could have are '0', '1', '2' ... '9'.
(s[i]>='0') && (s[i]<='9')
By subtracting '0' from s[i], code obtains the difference:
`0`-'0' --> 0
`1`-'0' --> 1
`2`-'0' --> 2
...
`9`-'0' --> 9
Code has successfully translated the character code for an numeric character into a corresponding integer value.
In your function, s is a sequence of ASCII encoded characters: a string. Actually, the encoding does not matter as long as it has the characters 0 through 9 as a sequence. Let's say it has the value "123ABC", for this explanation.
n is the output number. At the start of the function it is initialized to zero.
In the first iteration of the loop we have
i=0
s[i] = '1' (which is encoded as 49, in ASCII)
n = 0
so the math is like this:
n = n * 10 + (s[i] - '0')
n = 0 * 10 + ('1' - '0')
n = '1' - '0'
And converting the character syntax to the ASCII encoding gives this:
n = 49 - 48
n = 1
In the next iteration we have:
i = 1
s[i] = '2' (ASCII 50)
n = 1
n = n * 10 + (s[i] - '0')
n = 1 * 10 + ('2' - '0')
n = 10 + ('2' - '0')
n = 10 + (50 - 48)
n = 10 + 2
n = 12
And, in the third iteration:
i = 2
s[i] = '3' (ASCII 51)
n = 12
n = n * 10 + (s[i] - '0')
n = 12 * 10 + ('3' - '0')
n = 120 + ('3' - '0')
n = 120 + (51 - 48)
n = 120 + 3
n = 123
And, in the final iteration s[i] = 'A' which is not in the range specified by the if statement, so the loop exits.
As you can see it has correctly converted the string "123" to the number 123.
Related
So I was assigned to store two 50 digit integers in c language and do math equations using them. the problem for me was to store the input digit by digit in an array. I figured that I can store the input in a char string like this:
#include <stdlib.h>
#include <stdio.h>
int main ()
{
char string_test [50];
scanf("%s", string_test);
return 0;
}
But I couldn't use it as a number because it was stored as char and I couldn't copy them digit by digit into another array which was defined as int
after a whole day of searching, I found out that I need to copy my string one by one like this:
#include <stdlib.h>
#include <stdio.h>
int main ()
{
char string_test [50];
scanf("%s", string_test);
int arr[50];
for (int i = 0; i < 50; i++)
{
arr[i] = string_test[i] - '0';
}
return 0;
}
Now my question is why do I need to subtract '0' to get a suitable result?
The ASCII values for digits 0 - 9 are:
Digit 0 1 2 3 4 5 6 7 8 9
ASCII value 48 49 50 51 52 53 54 55 56 57
So if you have a string representation of an integer, say
char int_str[] = "123456";
and need to convert each char to its numeric value, subtracting the value for '0' (48) from each will will result in the values
int_str[0] == '1' ==> '1' - '0' ==> 42 - 41 == 1
int_str[1] == '2' ==> '2' - '0' ==> 43 - 41 == 2
int_str[2] == '3' ==> '3' - '0' ==> 44 - 41 == 3
int_str[3] == '4' ==> '4' - '0' ==> 45 - 41 == 4
int_str[4] == '5' ==> '5' - '0' ==> 46 - 41 == 5
int_str[5] == '6' ==> '6' - '0' ==> 47 - 41 == 6
To get digits 1 2 3 4 5 6 into the integer 123456 requires additional steps:
This example uses the same conversions encapsulated into a function to convert discrete char digit to int digit values, then assimilate each discrete int digit value into the composite integer value:
int main(void)
{
char str[] = "123456";
int int_num = str2int(str);
return 0;
}
int str2int(char *str)
{
int sum=0;
while(*str != '\0')
{ //qualify string
if(*str < '0' || *str > '9')
{
printf("Unable to convert it into integer.\n");
return 0;
}
else
{ //assimilate digits into integer
sum = sum*10 + (*str - '0');
str++;
}
}
return sum;
}
A char like '0' is just an ASCII representation of a 1 byte number. The numeric representations of these characters can be found in the manual (man ascii). Here you will see that '0' actually represents number 48 or 0x30 and that ASCII '0' to '9' are consecutive.
To convert a numeric char value to its integer counterpart, it is necessary to subtract this value of 48 or '0'.
I hope this clears things up. For further info, look into char arithmetic in C.
This is actually related to the ASCII code representation of numbers; when you input a character, '0', it is stored in memory as value 48 (in decimal) and also any other number or character.
You will find that the ASCII code value for '1' is 49 so, if we applied the operation, int x = '1' - '0';, we are storing the decimal value 1 in x and dealing with it as a number, not a character any more.
You can search more about ASCII codes; it's a very useful topic for any programmer.
I am trying to do some multiplication. I am asking users to enter 9 digits number and multiply each digit with. Lets say if user enters 123456789 then we will do this:
123456789
246824682
We will multiply user input with this code:
#include <stdio.h>
int main(void) {
char num[10];
int num1,num2,num3;
printf("Enter your num: ");
fgets(num,10,stdin);
num1 = num[1] * 2;
num2 = num[2] * 4;
num3 = num[3] * 6;
printf("%d %d %d", num1,num2,num3);
return 0;
}
When I run this this is what I get:
admin#matrix:~/cwork> ./lab2
Enter your num: 123
100 204 60admin#matrix:~/cwork>
Why am I getting 100 204 and 60
I though I would get : 2 8 18 OR 2818!
First, in the C programming language, arrays are indexed starting at 0. So you need to change the indexes from [1], [2], [3] to [0], [1], [2].
Second, each digit in the input is an ASCII character. So the character 2 is actually stored in your array as the number 50. That's why num[1] * 2 is 100.
The easiest way to convert the digits to the numbers you expect is to subtract '0' from each digit. Putting it all together, your code should look like this
num1 = (num[0] - '0') * 2;
num2 = (num[1] - '0') * 4;
num3 = (num[2] - '0') * 6;
When you read from stdin you get a char array.
So in your example with "123"
your array looks like this:
num[1] == '2' == 50 // 50 is the ascii code for '2'
num[2] == '3' == 51 // 51 is the ascii code for '3'
So of course you are getting 100, 204 for these numbers.
Also note that arrays start with 0, not with 1!
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
The following code prints out 5. Can someone explain it to me? I think I am mostly confused about the math; for example, using '0' instead of 0 and how I can do that math on paper...
#include <stdio.h>
int main (int argc , char * argv [])
{
char * c_pt ;
int n = 0;
if( argc == 2)
{
c_pt = argv [1];
while (* c_pt )
{
if (* c_pt < '0' || * c_pt > '1') break ;
n = n*2 + * c_pt - '0';
c_pt ++;
}
printf ("%d\n", n);
}
}
When you access the characters in a string containing digits you might get the character '0' or '1' for example. But the integer value of '0' is 48 and the integer value of '1' is 49 so if you want to turn them into the integers 0 and 1 for arithmetic you need to substract something. You could subtract 48 but then the next person that reads your code has no idea why you did that. So nornally you subtract the character represented by the value: '0' - '0' = 0 and '1' - '0' = 1
This particular program reads a string containing a binary number from the command line (so the string contains the characters '0' and '1') and converts that binary number to a decimal number by first converting the '0' and '1' at *c_pt to 0 and 1 and then adding it to the decimal number being built in n. It does that by starting with 0 and then on each iteration multiplying the number by two (which just shifts everything left one bit) and then adding the next digit. So if the string contained 10101 it would follow these steps:
number = 0
input = 10101
pointer = ^
number = number*2 + *pointer = 0*2 + ('1'-'0') = 0*2 + 1 = 1 (in binary: 1)
input = 10101
pointer = ^
number = number*2 + *pointer = 1*2 + ('0'-'0') = 1*2 + 0 = 2 (in binary: 10)
input = 10101
pointer = ^
number = number*2 + *pointer = 2*2 + ('1'-'0') = 2*2 + 1 = 5 (in binary: 101)
input = 10101
pointer = ^
number = number*2 + *pointer = 5*2 + ('0'-'0') = 5*2 + 0 = 10 (in binary: 1010)
input = 10101
pointer = ^
number = number*2 + *pointer = 10*2 + ('1'-'0') = 10*2 + 1 = 21 (in binary: 10101)
void main ( void )
{
int a[] = {22, 33,44};
'a' is a static array (or string) of 3 int, 22, 33, and 44.
int *x = a;
'x' is an int pointer, initialized to point to the same static array as 'a'.
printf (" sizeof ( int )=% lu ", sizeof (int ));
Prints the number of bytes [4] required to represent an int type on this system.
printf ("x=%p, x [0]=% d\n", x, x [0]);
Prints the memory address where the int pointer 'x' is currently pointing[0x7fff29af6530],
then also prints the integer value [22] stored in the [4] bytes starting at that address.
(Note: 'x[0]' is the same as '*x').
x = x + 2;
x [0x7fff29af6530]
+2 + 8 (or (2 * 4) or (2 * sizeof(int)))
---- ----------------
new x [0x7fff29af6538]
Advance the pointer 'x' 8 bytes.
The effect on 'x' is that it will now be pointing at its original memory address plus '(2 * sizeof(int))' bytes. 'a[2]' resolves to the same location.
printf ("x=%p, x [0]=% d\n", x, x[0]);
Prints the memory address where the int pointer 'x' is currently pointing [0x7fff29af6538]
then also prints the integer value [44] stored in the [4] bytes starting at that address.
Hence; 'x' now resolves to the same address as '&a[2]'; and '*x' resolves to the same number as 'a[2]'.
}
I tried to solve the problem on my own but got stuck after a while so looked at the solution.Question #8. And this is what I got.
#include <stdio.h>
int main(void)
{
char str[] =
"73167176531330624919225119674426574742355349194934"
"96983520312774506326239578318016984801869478851843"
"85861560789112949495459501737958331952853208805511"
"12540698747158523863050715693290963295227443043557"
"66896648950445244523161731856403098711121722383113"
"62229893423380308135336276614282806444486645238749"
"30358907296290491560440772390713810515859307960866"
"70172427121883998797908792274921901699720888093776"
"65727333001053367881220235421809751254540594752243"
"52584907711670556013604839586446706324415722155397"
"53697817977846174064955149290862569321978468622482"
"83972241375657056057490261407972968652414535100474"
"82166370484403199890008895243450658541227588666881"
"16427171479924442928230863465674813919123162824586"
"17866458359124566529476545682848912883142607690042"
"24219022671055626321111109370544217506941658960408"
"07198403850962455444362981230987879927244284909188"
"84580156166097919133875499200524063689912560717606"
"05886116467109405077541002256983155200055935729725"
"71636269561882670428252483600823257530420752963450";
size_t len = sizeof str - 1;
size_t i;
unsigned max = 0;
for (i = 0; i < len-4; i++) {
unsigned p = 1;
size_t j;
for (j = 0; j < 5; j++) {
p *= (unsigned)(str[i+j]-'0');
}
if (p > max) {
max = p;
}
}
printf("%u\n", max);
return 0;
}
My Problem : I didn't understand why there was -'0' in this line
p *= (unsigned)(str[i+j]-'0');
Sorry if my question is very stupid. But I can't seem to figure it out.
'0' - '0' == 0
'1' - '0' == 1
'2' - '0' == 2
etc.
Basically, it's for converting a char to its corresponding digit.
An explanation is that characters map directly to ASCII values:
'0' == 48
'1' == 49
'2' == 50
etc.
And the values are sequential. Therefore, when you subtract the lowest digit, you get the position after that digit, which will also be the int value of the digit.
Because that large block of digits is a string, each character is a text representation of a number rather than the number itself. If we take, for example the point at which i = 0 and j = 0, then str[i+j] is '7', note the quotes.
Now, characters in C are typically represented in ASCII, where every character is represented by a number from 0 to 255. '7' when converted to its numeric representation is equal to 55. See here for a table of ASCII values: http://www.asciitable.com/.
Note, now that all the numbers are sequential. The value of '0' is 48 and 57 minus 48 is 7. Subtracting '0' from a character representing a digit is a way to convert it back into the numeric representation of the digit.
I quite don't know what this loop does.
int atoi(char s[])
{
int i, n;
n = 0;
for (i = 0; s[i] >= '0' && s[i] <= '9'; ++i)
n = 10 * n + (s[i] - '0');
return n;
}
This part I don't get:
for (i = 0; s[i] >= '0' && s[i] <= '9'; ++i)
n = 10 * n + (s[i] - '0');
I get the whole for loop inside parentheses, and what s[i] - '0' does.
But I don't get what kind of operation is going on here --> n = 10 * n.
I don't know what n is representing and why is multiplying 10.
I know it's converting string of digits to numeric equivalent, but I just don't get the whole operation there.
But I don't get what kind of operation is going on here --> n = 10 * n
That's just how you build a number digit by digit. It's basically the same as it would work if you were writing a calculator. If I wrote a simple calculator, here's how it would handle the input 547:
Start with 0
5 ==> 0*10 + 5 = 5
4 ==> 5*10 + 4 = 54
7 ==> 54*10 + 7 = 547
Basically, atoi does, the exact same thing, but instead of reading each digit from button presses, it's reading them from a string. Each time you read a new digit, you do n *= 10 to make room for that next digit, which just gets directly added on the end.
n is the digits that has already been processed. For instance, for the string "123", first, the program gets digit 1, convert it to integer and store it in n, and then get the next digit 2, this is where n = 10 * n is useful, the previous 1 is multiplied by 10, and added to the next digit 2, the result is 12, and this is stored as the current n.
The same goes on, when processing 3, the previous stored 12 is multiplied by 10, results in 120 and added to 3, ended as 123 as result.