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

Jav*_*ier 3 c kernighan-and-ritchie

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;
}
Run Code Online (Sandbox Code Playgroud)

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

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

这里的错是什么?我真的不知道.

Ant*_*Ant 7

很多错误.你做这个:

last_space_idx = offset+i;
Run Code Online (Sandbox Code Playgroud)

但你也这样做:

temp = line[offset+last_space_idx];
Run Code Online (Sandbox Code Playgroud)

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

你也这样做:

offset = last_space_idx;
Run Code Online (Sandbox Code Playgroud)

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

Penny lane is
 in my ears
 and in my eyes
Run Code Online (Sandbox Code Playgroud)

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

if (c == '\n') { 
    s[i] = c; 
    ++i; 
}
Run Code Online (Sandbox Code Playgroud)

这意味着任何行返回都会被保留,所以如果您有There beneath\nthe blue suburban skies输入,您将获得此输出:

There beneath

the blue suburban skies
Run Code Online (Sandbox Code Playgroud)

最后,您读取的每个新行使用最后一个空格索引和前一行的偏移量.您需要在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;
}
Run Code Online (Sandbox Code Playgroud)