【问题标题】:Evergreen K&R ex. 1-21 entab常青K&R ex。 1-21 安塔布
【发布时间】:2021-04-07 12:26:40
【问题描述】:

这里的爱好者。在来这里之前我已经尽力了,我的解决方案“有点工作”,但并非总是如此,而且我发现调试这个“简单”问题特别困难。

“编写一个程序entab,用最少数量的制表符和空格替换空格字符串以实现相同的间距。使用相同的制表位,例如每n列。n应该是变量还是符号参数?”

为了帮助更容易理解我的代码,这里有一个简短的解释,所以希望有人能理解我想要做什么。

  1. 位置由制表符和任何其他非空格字符设置/增加,空格不会增加它。我将需要 pos 和 space_count 在第 3 步进行检查。
  2. 检查输入是否为空格或其他内容,如果是空格,则增加 space_count,如果不是,则执行步骤 2-3-4:
  3. 如果输入不是空格,首先我检查是否有足够的空格将它们转换为制表符,因此如果输入以 17 个空格开头并且制表符是 8 个空格,则打印两个制表符,将 space_count 减为 1 ,并将位置设置为第 16 列的第二个制表位。
  4. 在此之后,我检查剩余空格和当前位置的总和是否达到或超过下一个制表位,如果是,则打印一个制表符,将 space_count 递减到超出当前制表位的数量。
  5. 在所有这些之后,我使用 if - else if - else 分支来处理如果制表符、换行符或任何其他非空格字符是输入时会发生什么。由于这些与空间不同,可以立即打印,所以我打印它们。 (所以继续上面的例子,我有 2 个制表符,pos=16,space_counter = 1,下一个制表位在 24 处。如果我按字母 A,打印空格(在这种情况下为 1),打印 A,将位置设置为 18。现在如果我输入超过 5 个空格,第 3 步分支将执行为 18 + 6 = 24,所以我们到达下一个制表位。

对于我测试过的大多数输入,我猜它是可行的,但如果输入包含以下内容,我会得到不同的结果: “5 个空格,A,44 个空格,2 个制表符,3 个空格,A”(不是字面意思,所以它以 A 开头)。 如果我将 TAB_INC 设置为 8,并在记事本中检查它,它没有相同的间距(缺少 1 个制表符),所以结果不好。 如果我将 TAB_INC 设置为 4,并在 sublime 文本中检查它,如果我在那里复制源+结果一切都很好......所以除了无法调试它之外,我什至无法使用不同的文本编辑器获得相同的结果。

我的问题是,这个逻辑/代码为何或何时会中断?

代码是

#include <stdio.h>
#define TAB_INC 4

static int get_tab_stop(int pos) {
    return ((pos / TAB_INC) + 1) * TAB_INC;
}

static void init(void) {
    int c, pos, space_count;
    c = pos = space_count = 0;

    while (EOF != (c = getchar())) {
        if (' ' == c)
            ++space_count;
        else {
            while (TAB_INC <= space_count) {
                space_count -= TAB_INC;
                pos = get_tab_stop(pos);
                putchar('\t');
            }
            if (pos + space_count >= get_tab_stop(pos)) {
                space_count -= get_tab_stop(pos) - pos;
                pos = get_tab_stop(pos);
                putchar('\t');
            }
            if ('\t' == c) {
                space_count = 0;
                pos = get_tab_stop(pos);
            }
            else if ('\n' == c)
                pos = space_count = 0;
            else {
                pos = pos + space_count + 1;
                while (space_count) {
                    putchar(' ');
                    --space_count;
                }
            }
            putchar(c);
        }
    }
}

int main() {
    init();
    return 0;
}

【问题讨论】:

  • edit您的问题并添加示例输入以及针对好情况和坏情况的相应实际和预期输出。为了允许在输出中区分制表符和空格,您可以用两个字符 \t 替换制表符。可能同时显示正常和修改后的变体。

标签: c kernighan-and-ritchie


【解决方案1】:

实际上我发现了问题,第 2 步完全没有必要,它自己造成了问题,第 3 步需要返工。不管怎样,我把我的代码留在这里,它可能对将来解决这个问题的人有用。

#include <stdio.h>
#define TAB_INC 8

static int get_tab_stop(int pos) {
    return ((pos / TAB_INC) + 1) * TAB_INC;
}

static void init(void) {
    int c, pos, eval_ts, space_count;
    c = pos = eval_ts = space_count = 0;

    while (EOF != (c = getchar())) {
        if (' ' == c)
            ++space_count;
        else {
            while (pos + space_count >= (eval_ts = get_tab_stop(pos))) {
                space_count -= eval_ts - pos;
                pos = eval_ts;
                putchar('\t');
            }
            if ('\t' == c) {
                space_count = 0;
                pos = get_tab_stop(pos);
            }
            else if ('\n' == c)
                pos = space_count = 0;
            else {
                pos = pos + space_count + 1;
                while (space_count) {
                    putchar(' ');
                    --space_count;
                }
            }
            putchar(c);
        }
    }
}

int main() {
    init();
    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-25
    • 1970-01-01
    • 2011-04-06
    相关资源
    最近更新 更多