【问题标题】:What's wrong with my solution to K&R exercise 1-22?我对 K&R 练习 1-22 的解决方案有什么问题?
【发布时间】:2011-10-09 21:19:44
【问题描述】:

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

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

这是代码:

#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 在我的耳朵和我的眼睛里 在下面 郊区的蓝天

这是我得到的输出:

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

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

【问题讨论】:

  • 我必须问:你是在使用 ANSI 颜色代码将“Penny Lane”变成浅蓝色吗?那真的可以把事情搞砸了。

标签: c kernighan-and-ritchie


【解决方案1】:

很多错误。你这样做:

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;
}

【讨论】:

  • +1 用于printf 格式字符串。我从未见过这样写的长度说明符。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多