Question

A program that prints its input one word per line.

int main() {

    int c;

    while ((c=getchar()) != EOF) {

        if (c== ' ' || c== '\n' ||c == '\t')
                putchar('\n');
        else {
            putchar(c);
        }
    }
    return 0;
}

The above program prints the result correctly, one word per line. After changing the condition accordingly, I was expecting the program below to also print one word per line. However I am not getting the correct result. Am I making some silly mistake or is something wrong?

int main() {

    int c;

    while ((c=getchar()) != EOF) {

        if (c != ' ' || c != '\n' || c != '\t')
            putchar(c);
        else {
            putchar('\n');
        }
    }

    return 0;

}
Was it helpful?

Solution

the correct change of condition is:

if (!(c == ' ' || c == '\n' || c == '\t'))

or

if (c != ' ' && c != '\n' && c != '\t')

See De Morgan's law

OTHER TIPS

You've gotten a number of answers to your original question, but I feel obliged to add one minor detail: both the original and the modified version suffer from a couple of what I'd consider problems. First, they don't really detect white-space correctly (e.g., they ignore vertical tabs, and any other white-space as defined by the locale), and they produce blank lines if words are separated by more than one white-space character.

For the first problem, I'd use isspace instead of directly comparing to the white-space characters you know about (incidentally, eliminating the source of the problem you encountered). For the second, you could add some logic to skip all consecutive white-space characters when you encounter the first, or you could add a flag to write out a new-line if and only if the current character is a space and the previous character you wrote was not a new-line.

Alternatively, you could read words using scanf with the %s conversion:

char buffer[256];

while (scanf("%255s", buffer))
    printf("%s\n", buffer);

This approach, however, imposes an upper limit on the size of a single word. Under normal circumstances, that's rarely problem, but depending on the nature of the input it could/can be.

You need to change the ||s to &&s, i.e. change

        if (c != ' ' || c != '\n' || c != '\t')

to

        if (c != ' ' && c != '\n' && c != '\t')

i.e. "IF c not equal to space AND c not equal to return AND c not equal to tab THEN ..."

Remember your logic programming classes:

!(A || B) == (!A && !B)
!(A && B) == (!A || !B)

In other words: your condition needs to read like this:

if ( c != ' ' && c != '\n' && c != '\t' )

You could do what MByD said, or you could change your or's (||) to and's (&&).

The error is in your conditional expression. When you negate the first expression

!(c== ' ' || c== '\n' ||c == '\t')

you get:

c!= ' ' && c!= '\n' &&c != '\t'

and not you defined in your question.

Remember:

(A && B) is the same as (!A || !B)

The opposite of A or B or C is not A and not B and not C, so use:

if(c != ' ' && c != '\n' && c != '\t')

You need to study a bit more on DeMorgan's Laws. It is not enough to change the combination operators from "||" to "&&", you must also negate all of the elements being combined to obtain the same solution set.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top