空白区域打印不正确

时间:2016-12-14 19:45:00

标签: c while-loop whitespace

我有这个程序:

int main(void)
{
    while ((c = getchar()) != EOF) {
        putchar(c);
        if (c == '{')
            spaces += 4;
        else if (c == '}')
            spaces -= 4;
        else if (c == '\n') {
            print_spaces(spaces);
            while ((c = getchar()) == ' ')
                continue;
            putchar(c);
        }
    }
}

void print_spaces(int spaces)
{
    while (spaces-- > 0)
        putchar(' ');
}

使用此输入运行时:

#include<stdio.h>
int main(void)
{
printf("hello, world!\n");
}

它只是打印确切的输入,而不是所需的输出 - 所需的输出是:

#include<stdio.h>
int main(void)
{
    printf("hello, world!\n");
}

我哪里出错?

3 个答案:

答案 0 :(得分:4)

这是因为正在通过换行符字符块中的{行读取字符while ((c = getc(f)) == ' ');。这就是为什么永远不会达到条件c == '{'并且空格计数器永远不会增加。

据我所知,这里有两件事:

  1. 缩进取决于缩进的两个字符序列\n{和缩进的\n}。您需要一些方法来传达上一个或下一个字符(下面是newline变量)。
  2. }{的范例略有不同,即打印和增量与减量和打印(有点像i++ vs ++i
  3. 下面的代码试图通过

    捕获这两点
    1. 更改空间计数器调整和打印的顺序
    2. 使用变量来传达前一个字符
    3. 话虽如此,它是非常简陋的,不处理角落案件或编码风格,而且很可能有更优雅的方式来做。

      `

       10     int newline = 0;
       11     while ((c = getc(f)) != EOF) {
       12         if (c == '}') {
       13             spaces -= 4;
       14         }
       15         if (newline == 1) {
       16             print_spaces(spaces);
       17             newline = 0;
       18         }
       19         putchar(c);
       20         if (c == '{') {
       21             spaces += 4;
       22         } else if (c == '\n') {
       23             newline = 1;
       24             while ((c = getc(f)) == ' ');
       25             ungetc(c, f);
       26         }
       27     }
      

      `

答案 1 :(得分:1)

;条件的末尾有一个额外的while,它可能是故意的,但却非常具有误导性:它看起来像一个bug。您应该添加continue语句或空块{}以强调空语句为有意的:

    while ((c = getc(f)) == ' ')
        continue;

您的方法存在一些问题:

  • 如果不是EOF,你应该取消最后一个字节,这样就可以在主循环中测试它。这是您的问题的原因:{只是在\n之后复制而spaces没有增加。
  • 您还应该跳过制表符并专门处理换行符,否则空白行将阻止下一行的正确缩进。
  • ;终止的行应导致延续缩进,可能会导致不同于4的特定数量。

这是一个改进的代码片段,仅解决前两个问题:

while ((c = getc(f)) != EOF) {
    putchar(c);
    if (c == '{') {
        spaces += 4;
    } else
    if (c == '}') {
        if (spaces >= 4) {
            spaces -= 4;
        }
    } else
    if (c == '\n') {
        /* consume all white space except newlines */
        while (isspace(c = getc(f))) {
            if (c == '\n')
               putchar(c);
        }
        if (c != EOF) {
            ungetc(c, f);
            /* print the indentation if further code is present */
            print_spaces(spaces);
        }
    }
}

答案 2 :(得分:0)

你的代码有点令人困惑。

int printspaces = 1; // initial spaces are ignored.
while ((c = getc(f)) != EOF) {
    if(printspaces == 1)
    {
        print_spaces(spaces);
        printspaces = 0;
        if(c == ' ')
            while((c = getc(f)) == ' ');
    }
    putchar(c);
    switch(c)
    {
        case '{':
            spaces += 4;
            break;
        case '}':
            if(spaces >= 4)
                spaces -= 4;
                break;
        case '\n':
            printspaces = 1;
            break;
        default:
            break;
    }
}