【问题标题】:understanding detab in K&R了解 K&R 中的 detab
【发布时间】:2014-10-14 07:16:14
【问题描述】:

我正在自学 C 并通过 K&R 工作。我正在做练习 1-20:

编写一个程序entab,用最少数量的制表符和空格替换空格字符串,以实现相同的间距。使用与 detab 相同的制表位。

我自己完成了这个程序,但正在审查其他解决方案:

#include<stdio.h>
#define TABINC 8

int main(void)
{
  int nb,pos,c;

  nb = 0;
  pos = 1;

  while((c=getchar())!=EOF)
  {
    if( c == '\t')
    {
      nb = TABINC - (( pos - 1) % TABINC);   // <---- How does this work

      while( nb > 0)
      {
        putchar('#');
        ++pos;
        --nb;
      }
    }
    else if( c == '\n')
    {
      putchar(c);
      pos = 1;
    }
    else
    {
      putchar(c);
      ++pos;
    }
  }

  return 0;
}

我很难理解这部分的工作原理nb = TABINC - (( pos - 1) % TABINC);。有人可以逐步解释这到底在做什么吗?或许可以给我举个例子?

谢谢。

【问题讨论】:

    标签: c tabs modulo kernighan-and-ritchie entab-detab


    【解决方案1】:

    考虑以下输入文本:

    \tone\ntwo\tthree\nsixteen\tseventeen\teighteen\n
    

    这是我们希望它产生的(标签替换为···):

             Column: |       |       |       |
             123456789012345678901234567890123
    Line: 1  ········one
          2  two·····three
          3  sixteen·seventeen·······eighteen
    

    每个制表符所需的空格数始终是从 1 到 TABINC(即 8)的数字(包括 8)。上例中的选项卡展开如下:

    Current   Next tab   No. spaces
    column#   position   required
       1          9         8
       4          9         5
       8          9         1
      18         25         7
    

    您应该能够在这里看到一个模式。如果我们已经在一个制表符位置(1、9、17 等),我们需要添加 8 个空格。一般来说,如果n 字符超过了一个制表符位置(0 &lt;= n &lt;= 7),那么我们需要添加8-n 空格。

    我们可以轻松计算n

    n = (pos - 1) % 8
    

    所以nb(我们需要添加的空格数)可以简单计算如下:

    nb = 8 - n
    

    因此

    nb = 8 - ((pos - 1) % 8)
    

    或者,更一般地说,

    nb = TABINC - ((pos - 1) % TABINC)
    

    【讨论】:

      【解决方案2】:

      感谢 r3mainer 的解释 这里给出了我的较短版本

      #include <stdio.h>
      
      #define TABW 8
      
      int main()
      {
          int c, pos;
      
          pos = 1;
          while ((c = getchar()) != EOF) {
              if (c == '\n') {
                  pos = 1;
                  putchar(c);
              }
              else if (c == '\t') {
                  for (int ns = TABW - ((pos - 1) % TABW); ns > 0; --ns) {
                      ++pos;
                      putchar(' ');
                  }
              }
              else {
                  ++pos;
                  putchar(c);
              }
          }
      
          return 0;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-12-04
        • 1970-01-01
        • 1970-01-01
        • 2017-12-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多