我的 K&R 练习 1-22 的解决方案有什么问题?

发布于 2024-12-08 16:59:49 字数 1590 浏览 1 评论 0原文

《C 编程语言》的练习 1-22 如下:

编写一个程序将长输入行“折叠”成两个或多个较短的输入行 在第 n 个之前出现的最后一个非空白字符之后的行 输入列。确保你的程序做了一些智能的事情 行很长,并且前面没有空格或制表符 指定列。

这是代码:

#include <ctype.h>
#include <stdio.h>

#define MAXLINE 500
#define FOLD_LENGTH 15

/* _getline:  read a line into s, return length  */ 
size_t _getline(char s[], int lim) 
{ 
    int c; 
    size_t i;

    for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i) 
        s[i] = c; 
    if (c == '\n') { 
        s[i] = c; 
        ++i; 
    } 
    s[i] = '\0'; 
    return i; 
}

int main()
{
    int c;
    char line[MAXLINE];
    char temp;
    unsigned last_space_idx = 0, i, offset = 0;

    while (_getline(line, MAXLINE) != 0) {
        for (i = 0; line[offset+i] != '\0'; i++) {
            if (i == FOLD_LENGTH) {
                temp = line[offset+last_space_idx];
                line[offset+last_space_idx] = '\0';
                printf("%s\n", line+offset);
                line[offset+last_space_idx] = temp;
                offset = last_space_idx;
                i = 0;
                continue;
            }
            if (isspace(line[offset+i])) {
                last_space_idx = offset+i;
            }
        }
        printf("%s\n", line+offset);
    }
    return 0;
}

这是我正在使用的示例输入:

Penny Lane is in my ears and in my eyes
There beneath
the blue suburban skies

这是我得到的输出:

Penny Lane is
 in my ears and in my ey
 and in my eyes

 eyes

 eyes

 eyes

这里有什么错误?我真的不知道。

Exercise 1-22 of The C Programming Language is as follow:

Write a program to "fold" long input lines into two or more shorter
lines after the last non-blank character that occurs before the n-th
column of input. Make sure your program does something intelligent
with very long lines, and if there are no blanks or tabs before the
specified column.

This is the code:

#include <ctype.h>
#include <stdio.h>

#define MAXLINE 500
#define FOLD_LENGTH 15

/* _getline:  read a line into s, return length  */ 
size_t _getline(char s[], int lim) 
{ 
    int c; 
    size_t i;

    for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i) 
        s[i] = c; 
    if (c == '\n') { 
        s[i] = c; 
        ++i; 
    } 
    s[i] = '\0'; 
    return i; 
}

int main()
{
    int c;
    char line[MAXLINE];
    char temp;
    unsigned last_space_idx = 0, i, offset = 0;

    while (_getline(line, MAXLINE) != 0) {
        for (i = 0; line[offset+i] != '\0'; i++) {
            if (i == FOLD_LENGTH) {
                temp = line[offset+last_space_idx];
                line[offset+last_space_idx] = '\0';
                printf("%s\n", line+offset);
                line[offset+last_space_idx] = temp;
                offset = last_space_idx;
                i = 0;
                continue;
            }
            if (isspace(line[offset+i])) {
                last_space_idx = offset+i;
            }
        }
        printf("%s\n", line+offset);
    }
    return 0;
}

This is the sample input I'm using:

Penny Lane is in my ears and in my eyes
There beneath
the blue suburban skies

And this is the output I get:

Penny Lane is
 in my ears and in my ey
 and in my eyes

 eyes

 eyes

 eyes

What's the bug here? I really have no clue.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

海螺姑娘 2024-12-15 16:59:49

很多错误。您这样做:

last_space_idx = offset+i;

但您也这样做:

temp = line[offset+last_space_idx];

这意味着 temp = line[(2 * offset) + last_observed_space_relative_to_offset]

您还可以这样做:

offset = last_space_idx;

这意味着偏移量等于最后观察到的空间,因此在第一行之后的每一行上都会有一个前置空格,如下所示:

Penny lane is
 in my ears
 and in my eyes

您的 _getline() 方法执行此操作:

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

这意味着保留任何行返回,因此,如果您将 There Below\nthe blue suburban skys 作为输入,您将得到以下输出:

There beneath

the blue suburban skies

最后,您读取的每个新行都使用最后一个空间索引以及相对于前一行的偏移量。您需要在 for 循环开始之前重置它们。

这是一个固定版本。我稍微整理了一下样式,并将 printf() bodge 替换为将打印子字符串的字符串格式。

#include <stdio.h>

#include <ctype.h>
#include <stdio.h>

#define MAXLINE 500
#define FOLD_LENGTH 15

size_t _getline(char s[], int lim);

/* _getline:  read a line into s, return length  */ 
size_t _getline(char s[], int lim) {

    char c; 
    size_t i;

    for (i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i) {
        s[i] = c;
    }

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

int main() {

    char line[MAXLINE];
    unsigned last_space_idx = 0;
    unsigned i;
    unsigned offset = 0;

    while (_getline(line, MAXLINE) != 0) {

        last_space_idx = 0;
        offset = 0;

        for (i = 0; line[offset+i] != '\0'; ++i) {
            if (i == FOLD_LENGTH) {
                printf("%.*s\n", last_space_idx, line + offset);
                offset += last_space_idx + 1;
                i = 0;
            } else if (isspace(line[offset + i])) {
                last_space_idx = i;
            }
        }

        printf("%s\n", line + offset);
    }
    return 0;
}

Lots of errors. You do this:

last_space_idx = offset+i;

But you also do this:

temp = line[offset+last_space_idx];

Which means that temp = line[(2 * offset) + last_observed_space_relative_to_offset].

You also do this:

offset = last_space_idx;

That means the offset becomes equal to the last observed space, so you'll have a preceding space on every line after the first, like this:

Penny lane is
 in my ears
 and in my eyes

Your _getline() method does this:

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

That means any line returns are preserved, so if you have There beneath\nthe blue suburban skies as the input you'll get this output:

There beneath

the blue suburban skies

Lastly, each new line you read uses the last space index and offset from the previous line. You need to reset them before the for loop starts.

Here's a fixed version. I've tidied up the style a little and replaced the printf() bodge with a string format that will print a substring.

#include <stdio.h>

#include <ctype.h>
#include <stdio.h>

#define MAXLINE 500
#define FOLD_LENGTH 15

size_t _getline(char s[], int lim);

/* _getline:  read a line into s, return length  */ 
size_t _getline(char s[], int lim) {

    char c; 
    size_t i;

    for (i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i) {
        s[i] = c;
    }

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

int main() {

    char line[MAXLINE];
    unsigned last_space_idx = 0;
    unsigned i;
    unsigned offset = 0;

    while (_getline(line, MAXLINE) != 0) {

        last_space_idx = 0;
        offset = 0;

        for (i = 0; line[offset+i] != '\0'; ++i) {
            if (i == FOLD_LENGTH) {
                printf("%.*s\n", last_space_idx, line + offset);
                offset += last_space_idx + 1;
                i = 0;
            } else if (isspace(line[offset + i])) {
                last_space_idx = i;
            }
        }

        printf("%s\n", line + offset);
    }
    return 0;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文