2014-02-23 92 views
1

我试图通过C编程语言书籍和即时通讯练习1-21,在那里你必须用适当数量的制表符和空格替换空格的块,以等于相同的空间,我能够让所有的东西都能正确运行和编译,但它会在输出中输入错误的制表符和空格。练习1-21 C编程语言

从本书中的实际问题:

写一个程序entab由最低 号标签和空白的空格替换字符串来实现相同的间距。与detab一样使用相同的 制表位。当选项卡或单个空白 就足以达到制表位,哪个应该给予优先?

再次,伙计们对编程仍然很陌生,所以请尽可能描述一下。

if I input something like asdf  asdf  asdf 
i get something like----- asdf    asdf    asdf back out. 

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#define MAX_BUFFER 1024 
#define SPACE  ' ' 
#define TAB   '\t' 
#define TabSize 4 


int main() 
{ 
    int c, i, j, spaces = 0, size, tempspaces, x, y, z; 
    int tabs = 0; 
    char arrayPrimary[MAX_BUFFER]; 
    char arraySecondary[MAX_BUFFER]; 
/* ********************************************************************** */  
    for(i = 0;(c = getchar()) != EOF && c != '\n'; i++) 
    { 
     arrayPrimary[i] = c; 
    } 
    arrayPrimary[i] = '\0'; 
    size = i; 
    printf("%s\n", arrayPrimary); 
/* ********************************************************************** */  
    for(i = 0, j = 0, tempspaces = 0; i < size; i++) 
    { 
     if(arrayPrimary[i] == SPACE) 
     { 
      tempspaces++; 
     } 
     else 
     { 
      arraySecondary[j] = arrayPrimary[i]; 
      j++; 
     } 
     if(tempspaces > 0 && arrayPrimary[i + 1] != SPACE) 
     { 
      spaces = tempspaces % TabSize; 
      printf("Spaces %i\n", spaces); 
      tabs = ((tempspaces - spaces)/TabSize); 
      printf("Tabs %i\n", tabs); 
      for(y = 0; y <= spaces; y++) 
      { 
        arraySecondary[j] = SPACE; 
        j++; 
      } 
      for(x = 0; x <= tabs; x++) 
      { 
       arraySecondary[j] = TAB; 
       j++; 
      } 
      tabs = 0; 
      spaces = 0; 
      tempspaces = 0; 
     } 

    } 
    arraySecondary[j + 1] = '\0'; 
    printf("%s\n", arraySecondary); 
    return 0; 
} 
+0

您在示例输入中说“类似”。这些是_exact_输入和输出,还是你只是输入“类似”他们?你如何查看输出结果?大多数终端的标签大小默认为8,但您的代码具有“TabSize 4”。 – Arkku

回答

1

在每次你要插入一个额外的空间和一个额外的标签最起码:

 for(y = 0; y <= spaces; y++) 

     for(x = 0; x <= tabs; x++) 

这些环路的两个从0到的空格/制表符,即号码,如果你每个有1个,循环将运行两次(0 <= 1,1 <= 1)。从条件中删除=

其次,大多数终端和编辑器不只是治疗选项卡作为等于一定数量的空间,而是标签是可变宽度的,取光标移到下一个标签停止。因此,例如,如果制表符停止四个空格分开,则字符串"123\tx""\tx"都会导致x以第4列中的同一制表符结束 - 第一个制表符相当于一个空格,而第二个制表符相当于四个空格......您的程序没有考虑到这一点。

要正确实现制表位,您需要跟踪当前列 - 该位置的制表符宽度将为TabSize - (column % TabSize)

它看起来也像你对我不终止arraySecondary正确:

arraySecondary[j + 1] = '\0'; 

你总是分配给循环内的数组后增加j,所以这应该是

arraySecondary[j] = '\0'; 

另外为此,请确保程序中定义的TabSize与您运行程序的终端的标签大小相匹配,否则即使程序正确,输出也不会在视觉上匹配。

+0

谢谢你,我有<=在那里因为我试图解决它为什么不工作,但谢谢你帮助我。 – Endon55

0

针对解决这个问题的算法。开始。

定义标签大小。创建并清空'输入'数组和'输出'数组。根据需要初始化数组和其他变量的索引变量。

首先,将整个输入行收集到一个名为'input'的数组中。然后,从“输入”开始,读取每个字符直到数组结束,并检查它是否是“空格”字符。如果它不是'空格'字符,请将其复制到'输出'数组中并继续下一个字符。如果它是一个'空格'字符,那么请记住我们找到'空格'的'输入'中的索引,并为任何连续的'空格'字符向前看'输入',并为我们遇到的每个'空格'字符增加一个计数器。当我们到达下一个非空间字符时,检查我们刚刚读取的“空格”字符数是否大于制表符大小。如果它大于制表符大小,则调用一个函数来获取空格的数量,作为制表符和空格的组合,并等于空格的数量并插入'输出'中。如果它不大于标签大小,那么我们不能放置'tab'字符,所以我们只需将所有空格复制到'output'中。如果我们能够调用entab函数,我们需要从我们已经记住的索引中恢复读取'输入',但是我们必须通过将我们遇到的'空格'字符的数目添加到记忆索引来跳过所有空格。

entab函数将不得不计算可以组合以实现实际间距的制表符和空格的数量。我们使用下面提到的公式计算到下一个制表符的距离:

x = tabSize - (currentInputIndex mod tabSize);

如果上述结果不为零,那么我们距离下一个制表符x个字符。现在插入一个'标签'。然后通过从原始空间数中减去x来重新计算剩余空间数。重新计算使用下面提到的公式所需的制表符和空格的数量:

nTabs = spacesRemaining/tabSize; nSpaces = spacesRemaining mod tabSize;

将nTabs'tab'和nSpaces'space'字符按顺序插入到'output'中。 entab函数应该将输出数组中的索引返回到主程序,以便它可以继续处理输入数组的其余部分。