c - C程序中的不一致

标签 c kernighan-and-ritchie

我正在查看练习的第二个解决方案:

http://users.powernet.co.uk/eton/kandr2/krx121.html

#include <stdio.h>

#define TABSTOP 4

int main(void)
{
    size_t spaces = 0;
    int ch;
    size_t x = 0;               /* position in the line */
    size_t tabstop = TABSTOP;   /* get this from the command-line 
                                 * if you want to */

    while ((ch = getchar()) != EOF)
    {
        if (ch == ' ')
        {
            spaces++;
        }
        else if (spaces == 0) /* no space, just printing */
        {
            putchar(ch);
            x++;
        }
        else if (spaces == 1) /* just one space, never print a tab */
        {
            putchar(' ');
            putchar(ch);
            x += 2;
            spaces = 0;
        }
        else
        {
            while (x / tabstop != (x + spaces) / tabstop) 
                /* are the spaces reaching behind the next tabstop ? */
            {
                putchar('\t');
                x++;
                spaces--;
                while (x % tabstop != 0)
                {
                    x++;
                    spaces--;
                }
            }

            while (spaces > 0) /* the remaining ones are real space */
            {
                putchar(' ');
                x++;
                spaces--;
            }
            putchar(ch); /* now print the non-space char */
            x++;
        }
        if (ch == '\n')
        {
            x = 0; /* reset line position */
        }
    }

    return 0;
}

我有两个用例:

  • 5 个字符,然后是 2 个空格,然后是一个字符,以及
  • 7 个字符,然后是 2 个空格,然后是一个字符。

在用例 1 中,x 在遇到第二个空格之前等于 5,在用例 2 中,x 在遇到第二个空格之前等于 7。但是在这两种情况下,在执行以下 block 之前都会出现 2 个后续空格:

while (x / tabstop != (x + spaces) / tabstop)

在条件中,请注意您在比较的两边将 x 除以制表位。唯一的区别是,在执行除法之前,在右侧将 x 递增一个空格。这是一个重要的区别。只要 spaces 等于 0,则两次除法返回相同的值,比较返回 true,while 不会执行。

但是,如果 spaces 大于 0,则此比较有可能返回 false。例如,如果 x 是 7:(7/4 != (7 + 1)/4),在这种情况下,while 循环将执行。但还有另一个变数。如果 x 不是 7,而是 5,并且 spaces 是 2,那么它将不会执行,因为 5/4 == 7/4,因为两者都产生 1(我们舍弃余数)。

为什么在 5 个常规字符后遇到第二个空格与在 7 个常规字符后遇到第二个空格在这里产生不同的结果?我不明白为什么在一种情况下它插入一个制表符而在另一种情况下它不插入,而在这两种情况下字符后面都有 2 个连续的空格。

最佳答案

您的代码与您引用的示例不同。

您引用的示例仅在出现四个连续空格时用制表符替换四个空格。

如果“单词”在制表位的倍数或之后开始,您似乎希望程序用制表符替换“单词”之间的空格。

两种不同的要求。

你说 5 个字符,加上两个空格,再加上一个字符应该导致用制表符替换两个空格,因为一个字符,第二个“单词”,从制表位开始。

while (x / tabstop != (x + spaces) / tabstop)

x 的值为 5,5/4=1。空格的值为2,(5+2)/4 = 1。等于。没有选项卡。程序正在做它被编程要做的事情。

您想用制表符替换这两个空格,因为第 8 个字符开始一个单词。

您的示例版本不会这样做。 x 的值为 7。

您似乎希望 x 的值为 8。5/4 = 1、8/4 = 2,替换制表符。

更改程序以在有两个或更多空格时将当前字符包括在计数中,看看会发生什么。

关于c - C程序中的不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20317382/

相关文章:

c - 如何在makefile中包含静态库

C 编程 - K&R 示例 1.5.2 - 修改后的程序未按预期运行

c - K&R 第 5.4 章 : Questions on passage regarding stacks

c - 删除尾随空格的程序不起作用! :(

c - 用命令行参数填充数组

c - 为什么构建.so文件涉及多个.c文件

c - mac osx 终端中的信号 EOF

c - 仅基于 printf 语句的程序段错误

iphone - 在没有 iphone 的情况下创建 Iphone 应用程序? (用iphone模拟器?)

c - 保护或加密来自 C 程序的输入/输出?