无法弄清楚C程序中的逻辑错误
一个程序,每行打印一个输入的单词。
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; }
条件的正确变化是:
if (!(c == ' ' || c == '\n' || c == '\t'))
要么
if (c != ' ' && c != '\n' && c != '\t')
参见德摩根定律
您已经获得了原始问题的一些答案,但我觉得有必要添加一个小细节:原始版本和修改版本都会遇到一些我认为有问题的问题。 首先,它们并没有真正正确地检测到空白区域(例如,它们忽略了垂直标签,以及区域设置定义的任何其他空白区域),如果单词被多个空格字符分隔,它们会产生空白行。
对于第一个问题,我使用isspace
而不是直接比较你知道的空白字符(顺便说一句,消除你遇到的问题的根源)。 对于第二个,你可以添加一些逻辑来跳过所有连续的空格字符,当你遇到第一个时,或者你可以添加一个标志来写出一个换行符当且仅当当前字符是一个空格和前一个字符你写的不是新行。
或者,您可以使用带有%s
转换的scanf
读取单词:
char buffer[256]; while (scanf("%255s", buffer)) printf("%s\n", buffer);
然而,这种方法对单个单词的大小施加了上限。 在正常情况下,这很少出现问题,但取决于输入的性质,它可以/可以。
你需要改变||
转到&&
s,即改变
if (c != ' ' || c != '\n' || c != '\t')
至
if (c != ' ' && c != '\n' && c != '\t')
即“IF c不等于空间而且c不等于返回而且c不等于tab THEN ……”
记住你的逻辑编程类:
!(A || B) == (!A && !B) !(A && B) == (!A || !B)
换句话说:你的病情需要像这样读:
if ( c != ' ' && c != '\n' && c != '\t' )
你可以做MByD所说的,或者你可以将你的(||)更改为和(&&)。
错误发生在条件表达式中。 当你否定第一个表达式时
!(c== ' ' || c== '\n' ||c == '\t')
你得到:
c!= ' ' && c!= '\n' &&c != '\t'
而不是你在问题中定义的。
记得:
(A && B)与(!A ||!B)相同
A or B or C
的反面not A and not B and not C
,所以使用:
if(c != ' ' && c != '\n' && c != '\t')
您需要更多地研究DeMorgan的法律 。 仅从“||”更改组合运算符是不够的 对于“&&”,您还必须否定所有要组合的元素以获得相同的解决方案集。