我正在查看练习的第二个解决方案:
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/