5

每行打印一个单词的程序。

int main() {

    int c;

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

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

上述程序正确打印结果,每行一个字。在相应地更改条件后,我期望下面的程序也每行打印一个单词。但是我没有得到正确的结果。我是在犯一些愚蠢的错误还是有什么问题?

int main() {

    int c;

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

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

    return 0;

}
4

8 回答 8

16

正确的条件变化是:

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

或者

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

参见德摩根定律

于 2011-05-16T20:55:40.203 回答
4

您已经获得了对原始问题的许多答案,但我觉得有必要添加一个小细节:原始版本和修改后的版本都存在一些我认为的问题。首先,它们并不能真正正确地检测到空白(例如,它们会忽略垂直制表符,以及由区域设置定义的任何其他空白),并且如果单词被多个空白字符分隔,它们会产生空白行.

对于第一个问题,我会使用isspace而不是直接与您知道的空白字符进行比较(顺便说一下,消除您遇到的问题的根源)。对于第二个,您可以添加一些逻辑以在遇到第一个字符时跳过所有连续的空白字符,或者您可以添加一个标志以写出一个换行符,当且仅当当前字符是空格并且前一个字符你写的不是换行符。

scanf或者,您可以使用转换来阅读单词%s

char buffer[256];

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

然而,这种方法对单个单词的大小施加了上限。在正常情况下,这很少有问题,但取决于输入的性质,它可能/可能是。

于 2011-05-16T21:08:19.577 回答
3

你需要把||s改成&&s,即改变

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

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

即“如果 c 不等于空格且 c 不等于返回且 c 不等于 tab THEN ...”

于 2011-05-16T20:56:06.277 回答
2

记住你的逻辑编程类:

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

换句话说:你的情况需要这样写:

if ( c != ' ' && c != '\n' && c != '\t' )
于 2011-05-16T21:00:14.480 回答
1

您可以按照 MByD 所说的去做,或者您可以将您的或 (||) 更改为与 (&&)。

于 2011-05-16T20:57:32.547 回答
0

错误在您的条件表达式中。当你否定第一个表达式时

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

你得到:

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

而不是您在问题中定义的。

记住:

(A && B) 与 (!A || !B) 相同

于 2011-05-16T20:57:55.063 回答
0

的反义词A or B or Cnot A and not B and not C,所以使用:

if(c != ' ' && c != '\n' && c != '\t')
于 2011-05-16T20:58:10.953 回答
0

你需要多研究一下德摩根定律。将组合运算符从“||”更改为不够 对于“&&”,您还必须否定所有被组合的元素以获得相同的解决方案集。

于 2011-05-16T21:01:07.593 回答