【问题标题】:Clarifying K&R exercise 1-9澄清 K&R 练习 1-9
【发布时间】:2015-04-29 19:10:35
【问题描述】:

我对这个练习有几个问题。这是我正在处理的代码:

#include <stdio.h>

int main (void)
{
    int c;
    int inspace;

    inspace = 0;
    while((c = getchar()) != EOF)
    {
        if(c == ' ')
        {
            if(inspace == 0)
            {
                inspace = 1;
                putchar(c);
            }
        }

        if(c != ' ')
        {
            inspace = 0;
            putchar(c);
        }
    }
    return 0;
}

(抱歉,我在理解这些程序的工作原理时遇到了很多麻烦,因为它们非常简单,而且缺乏对它们实际工作方式的描述)

首先,putchar(c) 怎么不输出与进来的完全相同的数据。尽管它检查一个空白或 != 空白,它仍然说输出“c”,这只是 getchar(c) 的意思无论输入什么。我没有看到指定删除多余空格并仅输出一个空格的代码。代码在哪里指定必须发生的事情?在我看来,我无法理解 getchar/putchar 的工作原理。

另外,inspace == 1 或 0 有什么重要性?如果 inspace 为 == 1,那么它只会输出输入的字符。没有什么说删除了多余的空格,并且除了 0 或 1 之外没有将 inspace 定义为任何东西,没有将它定义为空格,那么它怎么可能对程序正在做什么有任何真正的意义呢?

我真的很困惑,替换空格的代码在哪里,它是如何工作的?有没有我应该学习的更简单的书来解释解决方案?

【问题讨论】:

  • 如果它读取了一个空格,但它之前读取了一个空格(因为inspace == 1),它不会调用putchar(c),因此输出与输入不同。
  • 不确定究竟是什么导致了您的困惑。你知道=== 之间的区别吗?您说“如果 inspace 为 == 1,那么它只会输出输入的字符。”,但这与发生的情况相反。
  • 好吧,你说得对,我不是很清楚。我没有得到的是它删除额外空格的地方。在我看来,不管它说什么 putchar(c) 其中 C 代表输入的内容,我错了吗?删除/替换发生在哪里?我知道程序必须输出相同的字符,但它还必须用一个空格替换双空格,我看不出这是在哪里发生的。

标签: c


【解决方案1】:

首先,putchar(c) 怎么不输出与进来的完全相同的数据。尽管它检查一个空白或 != 空白,它仍然说输出“c”,这只是 getchar(c) 的意思无论输入什么。我没有看到指定删除多余空格并仅输出一个空格的代码。代码在哪里指定必须发生的事情?在我看来,我无法理解 getchar/putchar 的工作原理。

if putchar 被调用是正确的,它只是输出输入字符。这个程序的关键是 putchar 不会在每个输入字符上调用。各种if 语句控制何时调用它。在高层次上,如果连续有多个空格,程序会避免在第二个、第三个、第四个等空格上调用 putchar。它只在第一个空格上调用。

另外,inspace == 1 或 0 有什么重要性?如果 inspace 为 == 1,那么它只会输出输入的字符。没有什么说删除了多余的空格,并且除了 0 或 1 之外没有将 inspace 定义为任何东西,没有将它定义为空格,那么它怎么可能对程序正在做什么有任何真正的意义呢?

不要将其视为被删除的空格。将其视为省略。有时调用 putchar ,有时不调用。查看循环并尝试找出哪些条件会导致调用 putchar not

重要的是,看看如果你开始循环迭代,inspace == 1c == ' ' 会发生什么。会发生什么?

将一个表格显示何时调用和不调用 putchar 可能会有所帮助。

Is putchar(c) called?
=====================

             | c == ' ' | c != ' '
-------------+----------+---------
inspace == 0 |    Y     |    Y
inspace == 1 |    N     |    Y

【讨论】:

    【解决方案2】:

    当输入中有两个或更多连续的' ' 字符时,请考虑此块中的逻辑。

        if(c == ' ')
        {
            if(inspace == 0)
            {
                inspace = 1;
                putchar(c);
            }
        }
    

    当遇到第一个空格字符时,代码进入嵌套的if 块并打印该字符。

    遇到第二个空格字符时,代码不进入嵌套的if块,不打印字符。

    如果你遵循这个逻辑,你会注意到如果输入中有两个或多个连续的空格字符,则只打印一个。

    【讨论】:

    • 这个答案让我意识到另一个人所说的话,而他的建议又进一步帮助了我等等。非常感谢大家。
    【解决方案3】:

    putchar(c) 如何不输出与传入的完全相同的数据。

    当代码到达putchar(c) 时,它会输出与传入的完全相同的字符。但是,在某些迭代中代码可能不会到达putchar(c)

    inspace == 10 有什么重要性?

    一旦程序将inspace 设置为1,它就会停止打印更多的空格字符,因为代码在循环的第二次和后续迭代中不会到达putchar(c)

    inspace 设置为1 在打印一个或多个空格序列中的第一个空格之后。如果inspace 设置为零进入第一个条件,则会打印一个空格;否则,不会打印空格。

    这是一个解释正在发生的事情的图表:

    程序从黑色圆圈开始,然后根据输入的字符进入两种状态之一:

    • 如果字符是空格,则进入左边的状态,当打印第一个空格时,其余空格被忽略(即inspace设置为1
    • 如果字符不是空格,则在打印每个字符时进入右侧的状态。
    • 每次读取新字符时,程序都会决定是切换状态还是保持当前状态。

    注意:图中没有显示EOF 以节省一些空间。当达到EOF 时,程序退出。

    【讨论】:

      【解决方案4】:

      第一个if 块和内部块说:“如果输入是空格并且inspace 标志为零,则打印它,并将标志设置为1”。 IE。如果是第一个则打印空格,并指示下一个不会是第一个。第二个块说“如果输入不是空格,则打印它并重置先前的空格标志,以便下一个遇到的空格将被视为第一个。”。就是这样。

      【讨论】:

        猜你喜欢
        • 2020-06-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-12-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多