演習5-13 K&R プログラミング言語C

演習5-13

読み込んだ行を、引数で与えられたサイズのリングバッファ配列に保存していく。
readlines はリングバッファ配列内の読み出し開始インデックスを返すように修正した。
writelines は読み出し開始インデックスを引数にとるように修正した。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define DEFAULT_LINE_SIZE 10
#define ALLOCSIZE 50000 /* 使用可能な場所の大きさ */
#define MAXLINES 5000 /* 読み込むファイルの最大行数 */
#define MAXLEN 1000 /* 任意の入力行の最大長 */

char allocbuf[ALLOCSIZE]; /* alloc のための記憶場所 */
char *allocp = allocbuf;  /* 次の空き位置(allocbuf の先頭アドレスを指して初期化) */
char *lineptr[MAXLINES];  /* テキスト行へのポインタ */

char *alloc(int n);
void afree(char *p);
int my_getline(char*, int);
int readlines(char *lineptr[], int nlines);
void writelines(char *lineptr[], int nlines, int start);

int main(int argc, char *argv[])
{
    int start_index;
    int n = DEFAULT_LINE_SIZE;

    while (--argc > 0 && **++argv == '-') {
        if (**argv == '-') {
            if ((n = atoi(*argv + 1)) <= 0) {
                n = DEFAULT_LINE_SIZE;
            }
        }
    }

    if ((start_index = readlines(lineptr, n)) >= 0) {
        writelines(lineptr, n, start_index);
        return 0;
    } else {
        fprintf(stderr, "error: input too big to read\n");
        return 1;
    }
}



/* n 文字へのポインタを返す */
char *alloc(int n)
{
    if (allocbuf + ALLOCSIZE - allocp >= n) { /* 入りきる */
        allocp += n;
        return allocp - n; /* 古い p */
    } else { /* 十分な空きがないとき */
        return 0; /* 異常事態を表わす 0 、通常は NULL (stdio.h で定義) を使う */
    }
}

/* p によって指される領域を解放する */
void afree(char *p)
{
    if (p >= allocbuf && p < allocbuf + ALLOCSIZE) {
        allocp = p;
    }
}

/* readlines : 入力行を読み込む */
int readlines(char *lineptr[], int maxlines)
{
    int len, nlines;
    char *p, line[MAXLEN];

    nlines = 0;
    while ((len = my_getline(line, MAXLEN)) > 0) {
        if ((p = alloc(len)) == NULL) {
            return -1;
        } else {
            line[len-1] = '\0'; /* 改行を消す */
            strcpy(p, line);
            lineptr[nlines++ % maxlines] = p;
        }
    }
    return nlines % maxlines;
}

/* writelines : 出力行を書き出す */
void writelines(char *lineptr[], int nlines, int start)
{
    int i, j;

    for (i = start, j = 0; j < nlines; i++, j++) {
        printf("%s\n", lineptr[i % nlines]);
    }
}

int my_getline(char *s, int lim)
{
    int c, 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;
}
プログラミング言語C 第2版 ANSI規格準拠
B.W. カーニハン D.M. リッチー
共立出版
売り上げランキング: 9726
«
»