bornfree
bornfree

Reputation: 2528

Not able to figure out the logical error in C program

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;

}

Upvotes: 5

Views: 879

Answers (8)

MByD
MByD

Reputation: 137292

the correct change of condition is:

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

or

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

See De Morgan's law

Upvotes: 16

Jerry Coffin
Jerry Coffin

Reputation: 490108

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.

Upvotes: 4

Edwin Buck
Edwin Buck

Reputation: 70909

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.

Upvotes: 0

Marc Mutz - mmutz
Marc Mutz - mmutz

Reputation: 25293

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' )

Upvotes: 2

Mark Tolonen
Mark Tolonen

Reputation: 177564

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')

Upvotes: 0

Joao M
Joao M

Reputation: 684

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)

Upvotes: 0

Jim Clay
Jim Clay

Reputation: 1003

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

Upvotes: 1

Paul R
Paul R

Reputation: 212949

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 ..."

Upvotes: 3

Related Questions