K&R练习1.22出现问题,某些行超出了换行限制

时间:2018-12-05 14:24:23

标签: c

我正在阅读《 K&R》一书(《 C编程语言》),并且很难找出练习1.22的代码出了什么问题:

  

编写程序以将长输入行“折叠”成两个或更多   输入的第n列之前的最后一个非空白字符之后的较短行。确保您的程序执行了很长的行,并且在指定的列之前没有空白或制表符。

这是我的代码:

#include <stdio.h>
#define WRAP 40       // maximum output line length limit
#define MAXLINE 1000  // maximum input line length limit

int getLine(char line[]);

/* test getLine fuction */
int main(void) {
    int len;
    char line[MAXLINE];

    while ((len = getLine(line)) > 0) {
        printf("%s", line);
    }
}

/* getLine: read input and save it in line array; return its length.
 * folds long input lines into two or more shorter lines
 * after the last non-blank character that occurs before
 * the n-th column of input. */
int getLine(char line[]) {
    int c, i, j, count;

    i = 0;
    count = 0;
    while (i < MAXLINE && (c = getchar()) != EOF && c != '\n') {
        if (count == WRAP) {
            for (j = i; j >= 0 && line[j] != ' '; --j)
                ;

            // this line is to demonstrate the current c, j, i and count values
            printf("c: -%c-, j: %d, i: %d, count: %d\n", c, j, i, count);

            if (line[j] == ' ')
                line[j] = '\n';
            else {
                line[i] = '\n';
                ++i;
            }

            line[i] = c;
            ++i;
            count = 0;

        } else {
            line[i] = c;
            ++i;
        }

        ++count;
    }

    if (c == '\n') {
        line[i] = c;
        ++i;
    }

    line[i] = '\0';
    return i;
}

例如,我使用一个简单的lorem ipsum pragraph对其进行测试:

  

Lorem Ipsum只是印刷和排版行业的伪文本。自1500年代以来,Lorem Ipsum一直是行业的标准伪文本,当时一位不知名的打印机拿起一个厨房,将其打乱成一本样本书。它不仅生存了五个世纪,而且在电子排版方面也取得了飞跃,但基本上没有改变。它在1960年代开始流行,发布了包含Lorem Ipsum段落的Letraset工作表,最近又发布了包括Alres PageMaker在内的桌面发行软件,包括Lorem Ipsum的版本。

结果是:

c: -p-, j: 39, i: 40, count: 40
c: - -, j: 74, i: 80, count: 40
c: -d-, j: 119, i: 120, count: 40
c: - -, j: 157, i: 160, count: 40
c: -n-, j: 198, i: 200, count: 40
c: -b-, j: 239, i: 240, count: 40
c: -u-, j: 275, i: 280, count: 40
c: - -, j: 309, i: 320, count: 40
c: -a-, j: 355, i: 360, count: 40
c: -i-, j: 398, i: 400, count: 40
c: -i-, j: 434, i: 440, count: 40
c: -e-, j: 476, i: 480, count: 40
c: -i-, j: 518, i: 520, count: 40
c: -f-, j: 558, i: 560, count: 40
Lorem Ipsum is simply dummy text of the
printing and typesetting industry.
Lorem Ipsum has been the industry's standard
dummy text ever since the 1500s, when
an unknown printer took a galley of type
and scrambled it to make a type specimen
book. It has survived not only five
centuries, but also the leap into
electronic typesetting, remaining essentially
unchanged. It was popularised in the 1960s
with the release of Letraset sheets
containing Lorem Ipsum passages, and more
recently with desktop publishing software
like Aldus PageMaker including versions
of Lorem Ipsum.

如您所见,有些行超出了40个字符,例如,第三行的长度为44个字符,但是count变量不能捕获它!怎么了?

1 个答案:

答案 0 :(得分:1)

您在某处插入count = 0时重置了'\n'。如果您将其插入line[i],则可能是正确的。如果您将其插入line[j](使用j!=i)中,则必须考虑line[j]之后到line[i]之间的字符数。所以如果有line[j]之后的10个字符,您可能必须设置count = 10而不是0。(当然,您必须计算数字。)

我不确定一切是否都能按预期运行,因为

for (j = i; j >= 0 && line[j] != ' '; --j)
            ;

您比较line[i],但尚未将字符c写入此位置。 (您可以在检查包装后执行此操作。)

如果最后WRAP个字符中没有空格,则此循环甚至会在您之前插入的'\n'上运行,并在此之前插入'\n'。 尝试输入长行,例如 12345 12345 12345 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb(全部一行)。