《C - The Programming Language 2nd Edition》一书的练习 1-20

jos*_*ppa 2 c tabs replace space

目前我正在阅读“C - 编程语言”这本书,我对这个练习有一个问题:

“编写一个程序 'detab',用适当数量的空格替换输入中的制表符,以空格到下一个制表位。假设有一组固定的制表位,比如每个 n-colmuns。n 应该是变量还是符号参数?”

撇开我写这个程序的练习中的问题:

#include <stdio.h>

#define COLUMNS 5   /* number of columns for a tab */

int main()
{
    char c;
int i;

while ((c = getchar()) != EOF) {
    if (c == '\t') {
        for (i = 0; i < COLUMNS; i++)
            putchar(' ');
    }
    else
        putchar(c);
}

return 0;
}
Run Code Online (Sandbox Code Playgroud)

然后我在网上查了解决办法,发现了这个:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_BUFFER   1024
#define SPACE        ' '
#define TAB          '\t'

int CalculateNumberOfSpaces(int Offset, int TabSize)
{
   return TabSize - (Offset % TabSize);
}

/* K&R's getline() function from p29 */
int getline(char s[], int lim)
{
  int c, i;

  for(i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
    s[i] = c;
  if(c == '\n')
  {
    s[i] = c;
    ++i;
  }
  s[i] = '\0';

  return i;
}

int main(void)
{
  char  Buffer[MAX_BUFFER];
  int TabSize = 5; /* A good test value */

  int i, j, k, l;

  while(getline(Buffer, MAX_BUFFER) > 0)
  {
    for(i = 0, l = 0; Buffer[i] != '\0'; i++)
    {
      if(Buffer[i] == TAB)
      {
        j = CalculateNumberOfSpaces(l, TabSize);
        for(k = 0; k < j; k++)
        {
          putchar(SPACE);
          l++;
        }
      }
      else
      {
        putchar(Buffer[i]);
        l++;
      }
    }
  }

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我现在的问题是我的代码和其他代码之间的区别是什么。我认为练习会要求出现的每个 \t 都应替换为 n 个空格。

现在我不知道其他代码做了什么。

也许我对练习的理解有误。如果是这样,请向我解释。

谢谢你的帮助。


好的,这个解决方案怎么样:

    #include <stdio.h>

#define TAB 8   /* size of a tab */

int main()
{
char c;
int i,column = 0;

while ((c = getchar()) != EOF) {
    if (c == '\t') {
        for (i = column; i < TAB; i++){
            putchar(' ');
        }
        column = -1;
    }
    else{
        putchar(c);
        }
    column++;
}

return 0;
}
Run Code Online (Sandbox Code Playgroud)

新版本:

#include <stdio.h>

#define TAB 8   /* size of a tab */

int main()
{
char c;
int i,column = 0;

while ((c = getchar()) != EOF) {
    if(c == '\n')
        column = -1;

    if(column >= TAB)
        column = 0;

    if (c == '\t') {
        for (i = column; i < TAB; i++){
            putchar(' ');
        }
        column = -1;
    }
    else{
        putchar(c);
        }
    column++;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)

Fil*_*ves 5

你理解错了。您必须用空格替换每个制表符,直到下一个制表位。这完全取决于光标所在的位置。

因此,如果每 5 列有一个制表位,您可以将其视为:

-----|-----|-----|-----|-----|-----|-----|-----|-----|
Run Code Online (Sandbox Code Playgroud)

哪里|是制表位,-是一个字符。点击一个选项卡会将您带到下一个制表位。因此,例如,如果您从上一个制表位的开头写入 3 个字符,然后按制表符,则只需写入 2 个空格。