我在K&R Book,在试图寻找解决方案时,我遇到了以下代码:
int main()
{
int c;
while ((c = getchar()) != EOF) {
if (c == ' ') {
while ((c = getchar()) == ' ');
putchar(' ');
if (c == EOF) break;
}
putchar(c);
}
}
为什么即使我输入了一个字母,第一个if
语句仍然有效。根据我的理解,只有当我输入的字符是空白时,它才会执行?顺便说一句,这个练习是让一个程序将多个连续的空格替换为一个空格。
此程序打印除空白字符"之外的任何输入字符,直到用户中断输入为止。
在这个while循环中
while ((c = getchar()) == ' ');
读取但不输出每个空白字符。循环后,仅输出一个空白字符
putchar(' ');
也就是说,程序删除相邻的空白字符,在用户输入的字符序列中只留下一个空白字符。
我已经格式化并获得了代码。希望这会有所帮助。代码实际上隐藏了所有stdin
内的空间序列为一个空间:
"123 456 a b c " -> "123 456 a b c "
代码:
int main() {
int c;
/* we read stdin character after character */
while ((c = getchar()) != EOF) {
/* if we have read space */
if (c == ' ') {
/* we skip ALL spaces */
while ((c = getchar()) == ' ')
; /* skipping ALL spaces: we do nothing */
/* and then we print just ONE space instead of many skipped */
putchar(' ');
/* if we at the end of stdin, we have nothing more to print */
if (c == EOF)
break;
}
/* we print every non space character */
putchar(c);
}
}
只要输入流没有结束,它就会循环(EOF=文件结束)。
如果输入的字符是空格,它将忽略任何后续空格,然后只打印一个空格。
否则,它将输出输入的字符。
int main()
{
int c;
while ((c = getchar()) != EOF) {
对于输入的每个字符。。。
if (c == ' ') {
如果角色是一个空间。。。
while ((c = getchar()) == ' ');
这个循环跳过第一个…之后的所有空格。。。看到右边的分号,它可以读取字符,检查它是否是一个空格,对它什么都不做。这样写是一件非常棘手的事情,因为通常认为循环体将是下面的下一个语句,而它根本没有正文。在while
循环之后,你可以假设让你进入循环的条件是false,所以我们有一些正确的断言:在c
中肯定没有存储空间(它仍然可以是EOF
,它不是字符,所以我们需要在打印之前测试它,然后在下一个语句之后进行测试)
putchar(' ');
循环之后,只输出一个空格,对应于您在问题中提到的第一个if
语句中测试的空格。认为c
不是一个空格字符(所以我们不能putchar(c);
),因为我们跳过所有空格直到没有空格。它仍然可以是EOF
指示符,如下所示。
if (c == EOF) break;
如果字符不是空格,则它只能是EOF
指示符。在这种情况下,我们需要退出循环,这样我们就不会在下一个语句中打印它。。。
}
putchar(c);
由于我们一直在读取c
中的字符,直到我们得到一个非空格(也不是EOF
指示符,因为我们在这种情况下退出了上面的循环),我们无论如何都需要打印该字符。此putchar(c);
语句将始终打印一个非空格字符。它不在if
语句中,因为它必须针对最初非空格的所有字符和跟随空格序列的字符执行。
}
如上所述,我们可以假设循环的测试条件为false,因此在这里我们可以确保c
得到了EOF
(但这只是因为循环中的break
语句也发生在c == EOF
时)。
}
瞧!!!
备注
当试图找到解决方案时,我遇到了以下代码:
最后一点,如果您发布您的解决方案编程尝试,而不是通过搜索找到已经制定的解决方案,对您来说会更好。你会学到更多的编程知识,更少的谷歌搜索知识,而IMHO并不是你的主要兴趣。