练习1-21 C编程语言

时间:2014-02-23 20:58:08

标签: c

我试图通过C编程语言书和我的练习1-21,你必须用适当数量的标签和空格替换空格块以等于相同的空间,我能够得到一切正确运行和编译,但它不断在输出中放入错误数量的选项卡和空格。

书中的实际问题:

  

编写一个程序entab,用最小的替换空白字符串   标签和空白的数量,以实现相同的间距。使用相同的   制表位与详细信息相同。当标签或单个空白时   是否足以达到制表位,应优先考虑?

再一次,我仍然是编程的新手,所以请尽可能描述。

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;
}

2 个答案:

答案 0 :(得分:1)

至少你每次都要插入一个额外的空格和一个额外的标签:

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

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

这两个循环都从0到空格/制表符的数量,即如果每个都有1个,则循环将运行两次(0 <= 11 <= 1)。从条件中删除=

其次,大多数终端和编辑器不会简单地将标签视为等于一定数量的空格,而是将标签视为可变宽度,将光标移至下一个标签停止。因此,例如,如果制表符停止相隔四个空格,则字符串"123\tx""\tx"都会导致x在第4列的同一制表位结束 - 在第一个tab相当于一个空格,而在第二个空格中相当于四个空格......你的程序没有考虑到这一点。

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

在我看来,您还没有正确终止arraySecondary

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

在分配到循环内的数组后,总是递增j,所以这应该是

arraySecondary[j] = '\0';

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

答案 1 :(得分:0)

尝试解决此问题的算法。到此为止。

定义标签大小。创建一个&#39;输入&#39;数组和输出&#39;阵列。根据需要初始化数组和其他变量的索引变量。

首先,将整个输入行收集到一个名为&#39; input&#39;的数组中。然后,从输入&#39;的开头开始,读取每个字符直到数组的末尾,并检查它是否是一个空格&#39;性格与否。如果它不是一个空间&#39;字符,将其复制到&#39;输出&#39;数组并继续下一个字符。如果它是一个空间&#39;字符,然后记住输入&#39;中的索引。在那里我们找到了空间&#39;并展望未来的输入&#39;对于任何连续的空间&#39;字符并为每个空格增加一个计数器&#39;我们遇到的角色。当我们到达下一个非空间时字符,检查空格数是否为&#39;我们刚读过的字符大于标签大小。如果它大于制表符大小,则调用函数以将空格数量作为制表符和空格的组合等于空格数并插入“输出”。如果它不大于标签大小,那么我们就不能把标签放在标签上。字符,所以我们只需将所有空格复制到&#39;输出&#39;。如果我们能够调用entab函数,我们需要继续阅读&#39;输入&#39;从我们记住的索引,但我们必须通过添加“空格”的数量来跳过所有空格。我们在记住的索引中遇到的字符。

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

x = tabSize - (currentInputIndex mod tabSize);

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

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

插入nTabs&#39;标签&#39;和nSpaces&#39; space&#39;字符输入&#39;输出&#39;按顺序。 entab函数应该将输出数组中的索引返回给主程序,以便它可以继续处理输入数组的其余部分。