1

Following K&R, i wrote this program as an exercise. It was a while ago when I was still using Windows. Since then I have switched to Linux and the program won't run the way it used, even when simulating cmd in WINE.

#include <stdio.h>

#define IN 1 /* inside a word */
#define OUT 0 /* outside a word */

int main(){
    int c, state, nchar;
    int i, j; /* for loop variables */
    int charcount[15]; /* record word lengths from 1 to 15 characters */

    state = IN; /* start inside the word, if whitespace inputted on first key-press ++charcount[-1], which doesn't exist */
    nchar = 0; /* initialise word character count variable */
    for(i = 0; i<= 14; ++i) /* initialise word length array */
        charcount[i] = 0;

    printf("Input your text, then type ^Z(Ctrl + Z) on a new line for a word length distribution histogram.\n");
    printf("Special characters will be counted as part of a word.\n\n");

    while((c = getchar()) != EOF){
        if(state == IN){
        if(c == ' ' || c == '\n' || c == '\t'){
                if ((nchar - 1) <= 14) /* check if character count is above the limit of 15 */
                    ++charcount[nchar-1]; /* increase number of characters of this length, not count the last character inputed(space)*/
                else
                    ++charcount[14]; /* if character count > 15, increase 15+ section of the array(charcount[14]) */
            state = OUT; /* stop counting character */
        }
        ++nchar; /* increase character count of word if input isn't a whitespace */
        }
        else if(c != ' ' && c != '\n' && c != '\t'){ /* && not || because the latter is always true, fuuuuck i'm an idiot... */
                state = IN; /* go back to recording character count */
                nchar = 1; /* count latest character */
        }
    }

    for(i = 0; i< 14; ++i){ /* print histogram by looping through word length record up until 14 word character */
        printf("\n%4d:", i+1); /* define histogram section names */
        for(j = 0; j < charcount[i]; ++j) /* print bar for each section */
            putchar('-');
    }
    printf("\n%3d+:", 15); /* print bar for words 15+ characters long */
    for(j = 0; j < charcount[i]; ++j) /* print bar for 15+ section */
        putchar('-');

    return 0;
}

The program is supposed to print a histogram of the individual word lengths of an input text. To simulate the EOF character from the book I found out you have to press Control+Z on Windows. When I did that, the for loops at the ran and printed the histogram. When I do the equivalent on Linux(Control+D), the program simply stops. How should I solve this? I am guessing that using EOF as a trigger is a bad idea despite its use in K&R, os how should I change my program to make it reliable?

David Ranieri
  • 39,972
  • 7
  • 52
  • 94
Rares
  • 11
  • 2
  • Works fine on my linux, compiled with `gcc so.c -o so`, started, entered three words on their own lines and ending with CTRL+D However, it needs the newline before CTRL+D - maybe you need to make your stdin unbuffered, checkout `setbuf`? Edit: seems like `setvbuf` doesn't help here – LittleFox Sep 22 '22 at 08:07
  • Looking at [`man 3 stdin`](https://linux.die.net/man/3/stdin) notes that normal terminal input is line buffered in the kernel, I tried disabling canonical mode via termios, but then CTRL+D wasn't processed as EOF anymore – LittleFox Sep 22 '22 at 08:19
  • 1
    Read https://stackoverflow.com/questions/20028909/why-eof-is-recognized-if-it-is-first-character-in-line – Support Ukraine Sep 22 '22 at 08:40
  • May be a silly question: Why not simply use, for instance, 3 LFs in series to indicate end of input session... Back in the days of dial-up, a person often had 3 attempts at entering password before host would disconnect the line. Easy to do and "platform independent"... – Fe2O3 Sep 22 '22 at 08:42
  • and read https://stackoverflow.com/a/63542700/4386427 – Support Ukraine Sep 22 '22 at 08:43
  • 2
    Just read the code's comments. Wish more coders would admit that more often! `:-)` (We've all been there... `:-)`) – Fe2O3 Sep 22 '22 at 09:10
  • It works when I compile with gcc and run in a terminal, but when i run it in my ide(clion) it just exits with code 0. – Rares Sep 22 '22 at 11:31
  • So it is an issue with your IDE, not with your program. – the busybee Sep 22 '22 at 13:11
  • It's probably with the IDE but I still don't know how to fix it, also i want to know if there's a better way of going about this instead of checking for EOF. – Rares Sep 24 '22 at 09:06

0 Answers0