3

The C Programming Language的练习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 在我的耳朵和我的眼睛里
在下面
郊区的蓝天

这是我得到的输出:

便士巷是
 在我的耳朵和我的眼睛里
 在我眼里

 眼睛

 眼睛

 眼睛

这里有什么错误?我真的一点头绪都没有。

4

1 回答 1

7

很多错误。你来做这件事:

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 beneath\nthe blue suburban skies将输入作为输入,您将获得以下输出:

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;
}
于 2011-10-10T08:39:10.353 回答