K&R演習[1-17]

課題

一番長い行を印字するプログラムのmainルーチンを書き直して、任意の行の長さの入力行群の長さ、およびテキストの出来るだけ多くの部分を正しく印字するようにせよ。

回答

#include <stdio.h>
#include <limits.h>

#define MAX_LINE_NUM    1000        /* 入力行数の最大値 */
#define MAX_LENGTH      1000        /* 入力文字列長の最大値 */

typedef unsigned long long u8;

int getline(char line[], u8 maxline);
void copy(char to[], char from[]);


/**
 * @fn      Main
 * @brief
 * @param
 * @return
 * @detail
 */
int main(void)
{
    u8 i, len, num_line = 0;        // 行数
    char line1[MAX_LENGTH];                 // 保存元(読み取った文字列)
    char line2[MAX_LINE_NUM][MAX_LENGTH];   // 保存先

    while ((len = getline(line1, MAX_LENGTH)) > 0) {
        copy(line2[num_line], line1);       // 保存元から保存先へコピー
        num_line++;                         // 次の行へ
        if (num_line >= MAX_LINE_NUM) {     // 保存先の行数を使い切ったら終了
            break;
        }
    }

    printf("\n --- copy --- \n");                       // タイトル
    for (i = 0; i < num_line; i++) {                    // 保存した行数だけ
        printf("%d:%s", strlen(line2[i]), line2[i]);    // 保存先から取り出して印字
    }

    return 0;
}

/* getline: sに行を入れる */
int getline(char s[], u8 lim)
{
    int c;
    u8 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;
}

/* 行コピーする */
void copy(char to[], char from[])
{
    u8 i;

    i = 0;
    while (( to[i] = from[i]) != '\0') {
        ++i;
    }
}

実行内容

It is important to remember that it is never impossible to shake off an old habit and form a new one.
Once ahabit has been acqurired, it has almost compulsive power over us.

実行結果

--- copy ---
102:It is important to remember that it is never impossible to shake off an old habit and form a new one.
72:Once ahabit has been acqurired, it has almost compulsive power over us.