4

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;
}
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Bad Request
  • 3,990
  • 5
  • 33
  • 37
  • 1
    Nothing to do with your problem, but consider ditching DevC++. It is buggy and is no longer being developed. A good FOSS alternative is Code::Blocks at http://www.codeblocks.org. But as I said, this has NOTHING to do with your problem - switching IDEs won't fix it. –  Jan 04 '10 at 22:22
  • I had CB for a while. You wouldn't believe it, but there came a time when I simply didn't know how to *use* it :| Specifically the debugging feature: after I clicked on some grievously wrong button, it stopped showing me the list of errors in my code. After a couple days of digging around the documentation, I gave up and went back to the only IDE that I knew my way around :D – Bad Request Jan 04 '10 at 22:33
  • Anita, sorry to hear that. Did you try asking about your problem at http://forums.codeblocks.org. Or you could even try posting a question here on SO. Frankly, anything has got to be better than DevC++. –  Jan 04 '10 at 23:29

3 Answers3

7

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
  • 74,869
  • 16
  • 134
  • 187
  • 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! – Bad Request Jan 04 '10 at 22:04
  • 1
    If you want the same behaviour that K&R intended, you would benefit from running Linux in virtualbox :D – Hassan Syed Jan 04 '10 at 22:11
  • Thanks for the suggestion! I just looked up virtualbox. I'm having a mild case of info overload here. Damn this learning curve. – Bad Request Jan 04 '10 at 22:40
1

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.

Yevgeny Simkin
  • 27,946
  • 39
  • 137
  • 236
  • 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). – Bad Request Jan 04 '10 at 22:08
  • 1
    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. – Yevgeny Simkin Jan 04 '10 at 22:34
  • 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 :) – Bad Request Jan 04 '10 at 22:52
1

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
  • 885
  • 7
  • 6
  • 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. – Bad Request Jan 04 '10 at 22:38
  • 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 Jan 04 '10 at 23:35