【问题标题】:Exercise 1-21 C Programming Language练习 1-21 C 编程语言
【发布时间】:2015-08-11 20:31:39
【问题描述】:

我试图通过 C 编程语言书和我的练习 1-21 来工作,你必须用适量的制表符和空格替换空格块以等于相同的空间,我能够让所有东西都能正确运行和编译,但它总是在输出中放置错误数量的制表符和空格。

书中的实际问题:

编写一个程序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;
}

【问题讨论】:

  • 您在示例输入中说“类似”。这些是确切的输入和输出,还是你只是输入了“类似”的东西?你如何看待你的输出?大多数终端的标签大小默认为 8,但您的代码有 TabSize 4

标签: c


【解决方案1】:

至少您每次都插入一个额外的空格和一个额外的制表符:

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

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

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

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

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

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

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

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

arraySecondary[j] = '\0';

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

【讨论】:

  • 谢谢,我有
【解决方案2】:

尝试解决这个问题的算法。来了。

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

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

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

x = tabSize - (currentInputIndex mod tabSize);

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

nTabs = 剩余空间 / tabSize; nSpaces = spacesRemaining mod tabSize;

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-21
    • 1970-01-01
    相关资源
    最近更新 更多