3

The C Programming Language の演習 1-22 は次のとおりです。

入力のn番目の列の前にある最後の非ブランク文字の後で、長い入力行を 2 行以上の短い行に「折りたたむ」プログラムを作成してください。プログラムが非常に長い行で適切な処理を行っていること、および指定された列の前に空白やタブがないことを確認してください。

これはコードです:

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

これは私が使用しているサンプル入力です:

ペニー・レーンは私の耳と私の目にあります
その下にあります
青い郊外の空

そして、これは私が得る出力です:

ペニー・レインは
 私の耳と私の目で
 そして私の目に

 目

 目

 目

ここのバグは何ですか?私は本当に手がかりがありません。

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() ボッジを部分文字列を出力する文字列形式に置き換えました。

#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 に答える