我不明白这段代码是如何工作的
I don't understand how how this code works
我正在做 K&R 书中的练习 1-9,在尝试寻找解决方案时遇到了这段代码:
int main()
{
int c;
while ((c = getchar()) != EOF) {
if (c == ' ') {
while ((c = getchar()) == ' ');
putchar(' ');
if (c == EOF) break;
}
putchar(c);
}
}
为什么即使我输入了一个字母,第一个if
语句仍然有效。据我了解,它只会在我输入的字符为空白时执行 space?
顺便说一下,这个练习是让一个程序将多个连续的空白 space 替换为一个。
此程序打印除空白字符 ' ' 之外的任何输入字符,直到用户中断输入。
在这个 while 循环中
while ((c = getchar()) == ' ');
读取每个空白字符但不输出。而循环后只输出一个空白字符
putchar(' ');
即程序将用户输入的字符序列中相邻的空白字符去掉,只留下一个空白字符。
只要输入流没有结束(EOF = 文件结束),它就会循环。
如果输入的字符是space,它将忽略任何后续的spaces,只打印一个space。
否则输出输入的字符
我已经格式化并注释了代码。希望这会有所帮助。代码实际上隐藏了所有
stdin
中的 space 序列变成一个 space:
"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);
}
}
int main()
{
int c;
while ((c = getchar()) != EOF) {
对于输入的每个字符...
if (c == ' ') {
...如果字符是 space...
while ((c = getchar()) == ' ');
... 这个循环会跳过第一个之后的所有 space... 看右边的分号,它读取字符,检查它是 space , 而 对它什么都不做。 这样写是一件非常棘手的事情,因为通常认为循环 body 将是下面的下一个语句, 虽然它根本没有 body 。在 while
循环之后,你可以假设让你进入循环的条件为假,所以我们有一些正确的断言:在 c
中肯定没有 space 存储(它可以仍然是 EOF
,这不是一个字符,所以我们需要在打印之前对其进行测试,然后在下一条语句之后进行下一步)
putchar(' ');
... 循环后,只输出一个 space ,对应于您在问题中提到的第一个 if
语句中测试的那个。认为 c
不是 space 字符(所以我们不能 putchar(c);
),因为我们跳过所有 space 直到 none 仍然存在。它仍然可以是一个 EOF
指标,在下面检查。
if (c == EOF) break;
如果字符不是 space,它只能是 EOF
指示符。在那种情况下,我们需要跳出循环,这样我们就不会在下一条语句中打印它...
}
putchar(c);
... 因为我们一直在读取 c
中的字符,直到我们得到一个非 space (也不是 EOF
指示符,因为我们在上面的循环中case) 无论如何我们都需要打印那个字符。此 putchar(c);
语句将始终打印一个 non-space 字符。它在 if
语句之外,因为必须对所有最初为非 spaces 的字符和 spaces.[=35= 序列之后的字符执行此操作]
}
...如上,我们可以假设循环的测试条件为假,所以这里我们可以确保c
得到了EOF
(但只是因为break
循环内的语句也发生在 c == EOF
).
时
}
瞧瞧!!!
备注
while trying to find solutions I came across this code:
最后一点,如果您 post 尝试编写解决方案,而不是通过搜索找到已经制定的解决方案,那对您来说会更好。您将学到更多关于编程的知识,而不是谷歌搜索,恕我直言,谷歌搜索不是您的主要兴趣。
我正在做 K&R 书中的练习 1-9,在尝试寻找解决方案时遇到了这段代码:
int main()
{
int c;
while ((c = getchar()) != EOF) {
if (c == ' ') {
while ((c = getchar()) == ' ');
putchar(' ');
if (c == EOF) break;
}
putchar(c);
}
}
为什么即使我输入了一个字母,第一个if
语句仍然有效。据我了解,它只会在我输入的字符为空白时执行 space?
顺便说一下,这个练习是让一个程序将多个连续的空白 space 替换为一个。
此程序打印除空白字符 ' ' 之外的任何输入字符,直到用户中断输入。
在这个 while 循环中
while ((c = getchar()) == ' ');
读取每个空白字符但不输出。而循环后只输出一个空白字符
putchar(' ');
即程序将用户输入的字符序列中相邻的空白字符去掉,只留下一个空白字符。
只要输入流没有结束(EOF = 文件结束),它就会循环。
如果输入的字符是space,它将忽略任何后续的spaces,只打印一个space。
否则输出输入的字符
我已经格式化并注释了代码。希望这会有所帮助。代码实际上隐藏了所有
stdin
中的 space 序列变成一个 space:
"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);
}
}
int main()
{
int c;
while ((c = getchar()) != EOF) {
对于输入的每个字符...
if (c == ' ') {
...如果字符是 space...
while ((c = getchar()) == ' ');
... 这个循环会跳过第一个之后的所有 space... 看右边的分号,它读取字符,检查它是 space , 而 对它什么都不做。 这样写是一件非常棘手的事情,因为通常认为循环 body 将是下面的下一个语句, 虽然它根本没有 body 。在 while
循环之后,你可以假设让你进入循环的条件为假,所以我们有一些正确的断言:在 c
中肯定没有 space 存储(它可以仍然是 EOF
,这不是一个字符,所以我们需要在打印之前对其进行测试,然后在下一条语句之后进行下一步)
putchar(' ');
... 循环后,只输出一个 space ,对应于您在问题中提到的第一个 if
语句中测试的那个。认为 c
不是 space 字符(所以我们不能 putchar(c);
),因为我们跳过所有 space 直到 none 仍然存在。它仍然可以是一个 EOF
指标,在下面检查。
if (c == EOF) break;
如果字符不是 space,它只能是 EOF
指示符。在那种情况下,我们需要跳出循环,这样我们就不会在下一条语句中打印它...
}
putchar(c);
... 因为我们一直在读取 c
中的字符,直到我们得到一个非 space (也不是 EOF
指示符,因为我们在上面的循环中case) 无论如何我们都需要打印那个字符。此 putchar(c);
语句将始终打印一个 non-space 字符。它在 if
语句之外,因为必须对所有最初为非 spaces 的字符和 spaces.[=35= 序列之后的字符执行此操作]
}
...如上,我们可以假设循环的测试条件为假,所以这里我们可以确保c
得到了EOF
(但只是因为break
循环内的语句也发生在 c == EOF
).
}
瞧瞧!!!
备注
while trying to find solutions I came across this code:
最后一点,如果您 post 尝试编写解决方案,而不是通过搜索找到已经制定的解决方案,那对您来说会更好。您将学到更多关于编程的知识,而不是谷歌搜索,恕我直言,谷歌搜索不是您的主要兴趣。