Counting new lines, words, and characters

Thread Starter

asilvester635

Joined Jan 26, 2017
73
I have a program here that counts new lines, words, and characters. I get keyboard input from the user using getchar() as a condition in a while loop. After the while loop I display the number of new lines, words, and characters. My only problem is I don't know what keyboard input I should enter in order for the condition (c = getchar()) != EOF to be false. I checked what value EOF is by printing it, it printed -1, so I thought in order to step out of the while loop all I have to type in is -1, but the program still doesn't step out of the while loop to print the result. What should I do?

Code:
#include <cstdio>
#define IN     1    // inside a word
#define OUT 0    // outside a word

int main() {
// count lines, words, and characters in input
    int c = 0;    // hold the character being checked
    int nc = 0;    // hold count for new character
    int nl = 0;    // hold count for new line
    int nw = 0;    // hold count for new word
    int state = 0;

    state = OUT;
    while ((c = getchar()) != EOF) {
        // increment nc unconditionally
        ++nc;

        // check for a new line
        if (c == '\n') {
            ++nl;
        }

        // if c is space, tab, or new line, state will not be inside a word
        if (c == ' ' || c == '\t' || c == '\n') {
            state = OUT;
        } else if (state == OUT) {
            ++nw;
            state = IN;
        }
    } // end of while

    // print the number of new lines, characters, and words
    printf("There are %d new lines, %d characters, and %d words", nl, nc, nw);
} // end of main
 
Last edited:

djsfantasi

Joined Apr 11, 2010
9,163
That's probably because the Ctrl-Z is trapped by the OS and not passed on to the sketch. Could you code it to accept some other character to signify EOF? Such as a Ctrl-E? I don't think that is used by the OS.

Ctrl-E is a decimal 5.
 

MrSoftware

Joined Oct 29, 2013
2,202
What platform are you on? If you're on Linux/UNIX/similar then ctl-z will send the process to the background. Register an event handler to catch a different interrupt sequence, such as ctl-c. If you were on Windows, you could do it like this (other platforms are likely similar):

Code:
  // Register to catch interrupts
  if (SetConsoleCtrlHandler(&HandlerRoutine, true) == 0)
  {
    // Error failed to register interrupt handler
  }




  // Catch interrupts
static BOOL WINAPI HandlerRoutine(DWORD cwCtrlType)
{
  wcout << L"\n\n--- Caught interrupt of type: ";
  switch (cwCtrlType)
  {
  case CTRL_C_EVENT:
    wcout << L"ctl-c" << endl;
    break;
  case CTRL_BREAK_EVENT:
    wcout << L"ctl-break" << endl;
    break;
  case CTRL_CLOSE_EVENT:
    wcout << L"Close" << endl;
    break;
  case CTRL_LOGOFF_EVENT:
    wcout << L"Logoff" << endl;
    break;
  case CTRL_SHUTDOWN_EVENT:
    wcout << L"Shutdown" << endl;
    break;
  default:
    wcout << L"Unknown" << endl;
    break;
  }; // switch


return true;
}
https://msdn.microsoft.com/en-us/library/windows/desktop/ms686016(v=vs.85).aspx

https://msdn.microsoft.com/en-us/library/windows/desktop/ms683242(v=vs.85).aspx
 
Top