tags:

views:

356

answers:

3

I'm a total C n00b trying to teach myself C off K&R. My question is kind of embarrassingly elementary. OK, here goes: I can't get programs using getchar to give the kind of output I expected. If you happen to have K&R on hand, I'm stuck on exercise 1.13. The question goes, "Write a program to print a histogram of the lengths of words in its input. " and I can't even tackle the horizontal version because of this issue I'm having.

I'm on XP using Dev-C++ (mingW compiler) and running programs off the command line. My issue is, when I try to run my program, it waits for me to enter characters to scan from, but when I'm done inputting and hit Enter, it doesn't do anything. I expect it to go ahead and print the histogram as I expected. In reality, it doesn't even seem to count up word lengths, because as you can see in the code, when I try to print what's in the ctr array just to see if it contains anything, nothing prints.

I'm so n00b that I have no idea if it's my code or the command line that's at fault. But I suspect it's something with the system, because when I try to compile and run a model program, the same thing happens. Type in input, hit Enter, nothing happens. If I Ctrl-C, sometimes it spits out an asterisk or two that looks nothing like the model output. Other times, it doesn't do anything (just goes right back to the prompt).

Here's my code for the exercise. I've spent an entire day on this and am questioning my ability to carry on with programming. I'd really, really appreciate it if anyone could get me out of this hole!

Also, I have another question about the model program I mentioned above, but I think I should post it in its own question. Thanks all :)

#include <stdio.h>

//#define 1 IN
//#define 0 OUT
int main () {
    //start w/ state = OUT
    int c = 0;
//    int state = OUT;
    int len = 0;
    int ctr[12];
    int i, j;
    i = j = 0;

    for (i = 0; i <12; i++)
        ctr[i] = 0;
    while ((c = getchar()) != EOF)
       if (c != ' ' && c != '\t' && c != '\n') {
//            state = IN;
            len++;
            printf("%d", len);
            }
       else {
            ctr[len]++;
            len = 0;
            }            
    for (i = 0; i <12; i++) 
        printf("%d\n", ctr[i]);
    for (i = 0; i <12; i++) {
        printf("%d\n", i);   
        for (j = 0; j <= ctr[i]; j++)
            printf("-");
        printf("\n");
        }
    return 0;
}
+1  A: 

It doesn't look like you're actually storing c (your input) anywhere... nor printing it. You're printing the size of the string, but not the actual characters. If you ctr[i] = c; somewhere (that's you adding the character to the array), and then print the array, you'll see your input. Oh and yes, the answer about ctrl-z is also important. Also, if you're totally new to the language, I would strongly urge you to put brackets around your while content. It's going to be a while before you can just glance at the code and know what will fall into the purview of the while loop and what will not if you don't have braces around it.

Dr.Dredel
I'm afraid I don't quite get what you mean - perhaps a paraphrase, please? Thanks!If you're talking about the part where I loop through the array and print its contents, then yes, it's actually the number of chars in each word I'm interested in, not the words themselves (the exercise is to print a histogram of word lengths).
Anita
ah...I see. Ok well then the only thing to take away from my post is the thing about the brackets. while(1){ stuff goes here};. In your example you have an if/else that follows your while without brackets. Old school C didn't allow this, but modern compilers which know C++ don't mind. I'm just saying you should use the braces even if they're not mandatory, at least while you're getting to know the language, because you will get stuck with bugs like while(1){do stuff; do more stuff;} vs. while(1)do suff; do more stuff;. It looks similar but is VERY different.
Dr.Dredel
Very true. In fact, I spent an hour yesterday tracking down an else conditional that's gone wild (it started out with one statement under it, but later got expanded without my adding brackets). Will do that from now on - thanks :)
Anita
+7  A: 

Your while loop is looking for EOF which stands for end-of-file, not end-of-line.

On Windows, you need to type ctrl-z to simulate end-of-file.

R Samuel Klatchko
Argh! That's it! The books didn't tell me this. I wonder where I'd eventually learn this "fun fact" if you didn't come along. Thanks a mil!
Anita
Hassan Syed
Thanks for the suggestion! I just looked up virtualbox. I'm having a mild case of info overload here. Damn this learning curve.
Anita
+1  A: 

I didn't see anything really wrong with the code, so I loaded it up under gcc and it seems to work fine, as long as you remember that you have to put in an EOF (CTRL-D) to terminate the while loop. I entered 4 lines and while I can't make any statements about the correctness of the answers, each time I hit enter I got a series of numbers equal to the number of characters I entered, followed by a space. This is exactly what your code says to do.

When I entered the CTRL-D, I got the summary information. Again, I'm not going to make any statements about the correctness of the output, but I did get two major sections as described in your code.

jfawcett
It does print a histogram of sorts (with dashes)? That would be so awesome. I don't have any way to test my program right now.Also, I assume you're on Ubuntu? Because EOF simulation in Windows is apparently Ctrl-Z.
Anita
Yes, it printed a histogram of some sort. Like I said, I didn't even attempt to validate the output. My environment is actually Cygwin under Windows 7. Install the development kit and you've got gcc, gdb, etc. You can even start the X server and do GUI things.
jfawcett