7

I'm working with the Classic K&R Book "The C Programming Language", Second Edition.

I have this problem with the exercise in page 24 about Arrays.

Exercise say (Copy and paste from PDF):

#include <stdio.h>
/* count digits, white space, others */
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, other = %d\n",
        nwhite, nother);
}

In this case, the book says that after running the program the following output.

At this point the book is confusing because it does not say that the person typing ...

The output of this program on itself is digits = 9 3 0 0 0 0 0 0 0 1, white space = 123, other = 345

Ok, Now I'll put my copied code from the book

This is my exercise copied and paste from Eclipse:

#include <stdio.h>
#include <stdlib.h>

int main(void) {

    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(" After ");
    printf(" Var c %d \n", c);
    printf(" Var i %d \n", i);
    printf(" Var nwhite %d \n", nwhite);
    printf(" Var nother %d \n", nother);

    printf(" Digits are = ");
    for (i = 0; i < 10; ++i)
        printf(" %d ", ndigit[i]);

    return EXIT_SUCCESS;
}

When I run it and type anything like:

abc def ghi jkl 123

I obtain this output:

After Var c -1 Var i 10 Var nwhite 4 Var nother 13 Digits are =0 1 1 1 0 0 0 0 0 0

Resume:

My code only differs from the original in the last lines becose I use this printf to see the value of variables are taking.

And that I rename /|| c == '\n'/ because a dont want to count it like a nwhite.

The rest I think thats are equal and appears to work fine likes book example.

Question:

Why the values of the example they are telling me ?

My Question is that I do not understand this output means or that it related to the information I have entered:

Input: abc def ghi jkl 123

Output: Digits are =0 1 1 1 0 0 0 0 0 0

Final:

I would appreciate any explanation on this point that the book is not clear for my and not really understand that these values ​​are showing.

Added 05/06/2014:

SOLUTION TO MY DOUBT.

Firts

First of all I want to thank everyone for their help with the issue (links of the book), I thought it was in the public domain. I'll take this into account for future post.

Many thanks to: WhozCraig and Amir for their invaluable input and thanks to them finally able to understand the exercise.

And of course, to make sure I understood the next step is to perform verification that attached to help future readers to clarify this post:

To verify that I understood I made the following test:

In this new case we introduce the following series;

ab cd ef gh 1234136
After Var c -1
Var i 10
Var nwhite 4
Var nother 9
Digits = 0 2 1 2 1 0 1 0 0 0

And indeed the 0, and now whe have 2(ones) 1(two) 2(threes) 1(four), I have intentionally omitted five to checking 0(fives is OK) and finally 1(six), and the next for 7,8 and 9 are empy.

Thats is !!!

6
  • 2
    +1 for K&R and a clear first question Commented Jun 5, 2014 at 1:11
  • 1
    I seriously doubt that the publishers of K&R2 have given permission for their book to be published for free. I've deleted the link from your question. (The posted PDF omits the book's original copyright notice.) Commented Jun 5, 2014 at 1:31
  • 2
    Much as I respect Kernighan & Ritchie, I think this code seriously needs some curly brackets. Commented Jun 5, 2014 at 1:33
  • 1
    @MikeDunlavey yes people must appreciate this book and buy one. It's a great reference for C language. And yes I don't think it's allowed to be published online for free because a hard copy cost USD 70 Commented Jun 5, 2014 at 1:35
  • 2
    When the book says "The output of this program on itself is ", itself means that you use the program source as the input, e.g. you paste in the program source after you run the program and it is waiting for input; then you would get that result. In unix-style shells (which is the only thing K&R would have been using) you can achieve this with a command such as a.out <file.c. IDK if Eclipse has any such functionality, but (assuming you're in Windows) you could try opening a command prompt and doing myprogram.exe <myprogram.c if both of those files are in the directory. Commented Jun 5, 2014 at 1:39

2 Answers 2

2

Analyzing the output:

After Var c -1 Var i 10 Var nwhite 4 Var nother 13 Digits are =0 1 1 1 0 0 0 0 0 0
  • c -1 : You finished your read-loop with c equating to EOF, which on your platform is -1.
  • i 10 : The loop for (i = 0; i < 10; ++i) broke when i < 10 was no longer true. The last time it was touched was the final increment, ++i, that caused i to be 10 and has not been touched since.
  • nwhite 4 : There are four whitespace non-newline (because you eliminated it) chars in the character sequence you entered: abc def ghi jkl 123
  • nother 13 : The newline is counted as an "other" char per your modification, the digits are not. Therefore, abcdefghijkl\n are the thirteen values that contributed to this accumulation.

That leaves the last item:

Digits are =0 1 1 1 0 0 0 0 0 0

As you walk through the input data loop, when a digit char ('0'..'9') is encountered, its ASCII value (or, if you're running on an iSeries or zSeries, its EBCDIC value ), less the value of the char '0', creates a zero based index into an array of 10 integers. This works because the standard requires each of those code points for digit chars to be sequential and contiguous, and all platforms (including EBCDIC) honor this. The counter at that index in the array is incremented with each encounter of the corresponding digit char. When finished, the resulting array content is dumped to stdout. You had one digit each of '1', '2', and '3'. The first slot in your array is for '0', the next for '1', etc.. The 0 1 1 1 ... represents the number of zeros, ones, twos, threes, etc.

For more info on ASCII values see this table. If so inclined to see the differences with EBCDIC, see this table, and note that in both, though different actual numeric values, the full sequence '0'..'9' is contiguous.

Hope that helps. Well produced question, btw. Particularly for your first post.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for your perfect detailed explanation as well as I could understand at first. Unfortunately I find the book despite being a masterpiece, I have some dark areas.
1

I am reading this book right now and here's how I understand this.

The output you are getting is correct:

c = -1 because, the while loop exit when (c = getchar()) reaches EOF (knowing that EOF is equal to -1), and remember that you are storing the getchar() in c before comparing with EOF since parenthesis have higher priority. Therefore, the condition does: c = EOF, then it compares getchar() with EOF and exits the while loop

i = 10 because you are looping using a for loop, and when i reaches 10 it should stop. So last value store in i is 10.

0 1 1 1 0 0 0 0 0 0

means, you have

0 Zero
1 ONE
1 TWO
1 THREE
0 FOUR
etc...

PS: It's a great book!!

1 Comment

Thanks for your perfect detailed explanation as well as I could understand at first. Unfortunately I find the book despite being a masterpiece, I have some dark areas.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.