0

This code is expected to count the characters user inputed, except '\n', expect '\n's following other '\n'. I'll explain this later.

#include <stdio.h>

int main () {
        int numberOfChars = 0;

        do {
                while(getchar() != '\n')
                        numberOfChars++;
        } while(getchar() != EOF && numberOfChars++);

        printf("Number of chars = %d\n", numberOfChars);

        return 0;
}

Here are some examples:


Input: A, B, C, Ctrl + D

Expected output: 3

Actual output: Program doesn't terminate, and on the screen displays 123^D.


Input: A, B, C, Enter, Ctrl + D

Expected output: 3

Actual output: 3


Input: A, B, C, Enter, A, B, C, Enter, Ctrl + D

Expected output: 6

Actual output: 6


Input: A, B, C, Enter, Enter, Ctrl + D

Expected output: 4

Actual output: Program doesn't terminate, and on the screen displays:

abc

^D

I'm using OS X-10.10.5, bash-3.2 and clang-700.1.81.

Thanks in advance.

nalzok
  • 14,965
  • 21
  • 72
  • 139

4 Answers4

1

You have 2 getchar() calls - either one could read the EOF or '\n'. You need to refactor so there is only one getchar().

e.g. In your first example there is no '\n', so you never get out of the inner while loop. In your 4th example, the 2nd '\n' is read by the 2nd getchar and so you get stuck in the inner while again.

John3136
  • 28,809
  • 4
  • 51
  • 69
1

When the inner loop gets EOF returned, that is not equal to '\n', so the loop tries again, gets another EOF, and it still isn't a '\n', so it has another go. Computers are very patient…

In the inner loop, use:

int c;
while ((c = getchar()) != EOF && c != '\n')
    numberOfChars++;

This will stop on EOF or when the end of line is reached.

See also my discussion attached to your answer — though I missed the EOF problem for the inner loop.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • The loop will terminate not only for EOF but for '\n' as well. There is a criteria "expect '\n's following other '\n'" -- which implies '\n' should not stop the loop. – Siddhartha Ghosh Feb 09 '16 at 07:52
  • @SiddharthaGhosh: The outer loop deals with that — I merely didn't repeat the outer loop in my answer since I didn't propose any change to it. – Jonathan Leffler Feb 09 '16 at 07:56
  • Is there a need for 2 loops (outer and inner)? The count can be done with a single loop. – Siddhartha Ghosh Feb 09 '16 at 08:00
  • IMO, no there isn't a need for the two loops. However, the OP proposed the double loop as an answer to a question where the original code appeared to give an answer that was twice as big as expected because the OP of that question forgot (or didn't realize) that newlines are characters. See the link. In this context, the problem is "why does this double loop not terminate properly" rather than "is this a good way to count characters". – Jonathan Leffler Feb 09 '16 at 08:09
1

Slight modification to Jonathan's answer above (to ensure loop stops with EOF only, not '\n'):

EDIT: Also, this is single loop solution (without the need of outer and inner loops).

int c;
while ((c = getchar()) != EOF)
{
    if(c != '\n')  numberOfChars++;
}
Siddhartha Ghosh
  • 2,988
  • 5
  • 18
  • 25
  • Quite simple, but this will output 3 in my fourth example, where I expect a 4. – nalzok Feb 09 '16 at 08:44
  • In your 4th example, the output should be 3 only. As per the problem description in this question, "count characters ... except '\n', expect '\n's following other '\n'" -- so, that should exclude both the 'enter's. – Siddhartha Ghosh Feb 09 '16 at 08:58
  • This was my fault: Actually I meant "except ('\n', expect '\n's following other '\n')". English isn't my mother tongue. Sorry for that. – nalzok Feb 09 '16 at 09:21
0

First of, I have to apologize for the confusing description in my question:

...... except '\n', expect '\n's following other '\n'.

I meant:

...... except ('\n', expect '\n's following other '\n').

So there isn't a typo in my fourth example.

Finally, I came up with a solution:

#include <stdio.h>

int main () {
        int numberOfChars = 0;

        int c;
        do {
                while((c = getchar()) != '\n' && c != EOF )
                        numberOfChars++;
                while((c = getchar()) == '\n')
                        numberOfChars++;
        } while(c != EOF && numberOfChars++);

        printf("Number of chars = %d\n", numberOfChars);

        return 0;
}

I believe this code can demonstrate what I want well.

nalzok
  • 14,965
  • 21
  • 72
  • 139