-6

I input a bunch of digit characters, 3 4 5 6 6. And the code returns me this result

digits = 0 0 0 1 1 1 2 0 0 0, white space = 5
, other = 0.

I don't understand why the "digits" return me such a result 0 0 0 1 1 1 2 0 0 0. Can anyone explain why does the computer do that?

#include<stdio.h>

main()
{
int c, i, nwhite, nother;
int ndigit[10];

nwhite = nother = 0;
for (i = 0; i < 10; ++ i)
    ndigit[i] = 0;
while ((c = getchar()) != EOF)
    if (c >= '0' && c <= '9')
        ++ndigit[c-'0'];
    else if (c == ' ' || c == '\n' || c == '\t')
        ++nwhite;
    else
        ++nother;

    printf("digits =");
    for (i = 0; i < 10; ++i)
        printf(" %d", ndigit[i]);
    printf(", white space = %d\n, other = %d\n", nwhite, nother);
}
Jonathan Leffler
  • 698,132
  • 130
  • 858
  • 1,229
Bill Cao
  • 1
  • 1
  • What do you think the code is supposed to do? – John3136 Feb 02 '18 at 04:45
  • 3
    You code works and the result is perfect. What's wrong? – AndreyS Scherbakov Feb 02 '18 at 04:45
  • 2
    looks right to me. The index of the array is keeping track of how many of that number you entered (`c-'0'` turns the printable character entered into its number. `'0'` is 48 (in ASCII), so `'0' - '0'` is 48 - 48 = 0) .. and you entered zero 0s, zero 1s, zero 2s, one 3, one 4, one 5, two 6s, zero 7s, zero 8s, zero 9s, with five characters of white space. – yano Feb 02 '18 at 04:45
  • Is this code you wrote? – chux - Reinstate Monica Feb 02 '18 at 04:48
  • @Bill Cao: What do you want to get? – TigerTV.ru Feb 02 '18 at 04:57
  • No, the code is from C Programming Language. I just retyped them and try to get the concept behind this. – Bill Cao Feb 02 '18 at 05:08
  • I SEE NOW! I FINALLY GOT THIS, THANK YOU EVERYONE – Bill Cao Feb 02 '18 at 05:10
  • Replace `printf(" %d", ndigit[i]);` with `printf(" digit[%2d] : %d\n", i, ndigit[i]);` and try again `:)` (also remove `printf("digits =");`) – David C. Rankin Feb 02 '18 at 05:36
  • Welcome to Stack Overflow. Please note that the preferred way of saying 'thanks' around here is by up-voting good questions and helpful answers (once you have enough reputation to do so), and by accepting the most helpful answer to any question you ask (which also gives you a small boost to your reputation). Please see the [About] page and also [How do I ask questions here?](http://stackoverflow.com/help/how-to-ask) and [What do I do when someone answers my question?](http://stackoverflow.com/help/someone-answers) – Jonathan Leffler Feb 02 '18 at 05:48

1 Answers1

2

They key to understanding this problem is in this statement: ++ndigit[c-'0'];

The program begins by creating an array:

int ndigit[10]; /* creates an array of size 10 */

In c when you create an array, you just get a block of memory. What's in that memory is undefined. In more modern languages you may get an array of 10 zeros, but in c you could have garbage data in there when you first create it.

Walking through you code you should be able to identify how the program prepares the array for use. It makes sure each value at each index in the array is set to 0.

At this point your array and its indices looks something like this:

[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] /* array   */
  0  1  2  3  4  5  6  7  8  9   /* indices */

So if you were to run ndigit[0] you would get back the value at index 0, which is 0

c = getChar() is getting 1 character from the input (the numbers you typed). But at this point the program just sees those numbers as type char, not int. This is where you need to understand ASCII. Your first char input is '3'. This has an ASCII value of 51. The program performs this math: '3'-'0'. It is subtracting two chars. This is possible because c is just subtracting the ASCII value of these chars which is really 51-48 which equals 3.

The ++ operator increments a value: ie. ++0 increments 0 to 1. I won't get into pre vs post increment because you will learn that later.

Now that you have all of that, my suggestion is to draw a picture of what the array ndigit with its values and indices and the value of c (the current char) looks like at the end of each iteration of the while loop. Do this for each iteration of the while loop and you will see why the output you are seeing makes sense.

ie:

c = 3
[ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 ] /* array   */
  0  1  2  3  4  5  6  7  8  9   /* indices */

c = 4
...
...

/* and so on */

Here's a link to a useful ASCII table guide: http://www.asciitable.com/

Wilson
  • 251
  • 3
  • 9
  • 1
    Also worth referring him to [C11 Standard §5.1.2.2.1 Program startup p1 (draft n1570)](http://port70.net/~nsz/c/c11/n1570.html#5.1.2.2.1p1). See also: [See What should main() return in C and C++?](http://stackoverflow.com/questions/204476/) (P.S. well formatted and good effort) – David C. Rankin Feb 02 '18 at 05:43