また,明日学科のC言語のテストがある.C言語なぞ普段まったく使わないもんだから,思い出さねば.てことで,10行固定版tailを書いてみた.以下のソース.
うわ,長い.てか,キューとか限りなく無駄そう.Haskellとかだと限りなく短くなるんだろうなぁ.とか書いとくとid:omochistがHaskellで書いたtailを教えてくれそう.
って,数時間前にポストされたid:omochistの記事にtail載ってたー!ふつける:8章読んだという記事.たった6行なのだなぁ.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_STR 256
struct List {
struct List *next;
char line[MAX_STR + 1];
};
typedef struct List List;
struct Queue {
int max_size;
int current_size;
struct List *top;
};
typedef struct Queue Queue;
Queue *enqueue(Queue *q, char *line) {
List *new = NULL;
List *cur = NULL;
//サイズを超えていたら先頭から破棄
if (q->max_size <= q->current_size) {
List *tmp = q->top;
q->top = q->top->next;
free(tmp);
}
//ノード作成
if ((new = (List *)malloc(sizeof(List))) == NULL) {
fprintf (stderr, "allocation error\n");
}
strncpy(new->line, line, MAX_STR);
new->next = NULL;
//ノードをキューに追加
if (q->top == NULL) {
q->top = new;
} else {
for (cur = q->top; cur->next != NULL; cur = cur->next);
cur->next = new;
}
q->current_size += 1;
return q;
}
Queue *dequeue(Queue *q, char *line) {
//無効なキューのチェック
if (q == NULL) {
return NULL;
} else if (q->top == NULL) {
return NULL;
}
//データ読み出し
strncpy(line, q->top->line, MAX_STR);
//ノード破棄
List *tmp = q->top;
q->top = q->top->next;
free (tmp);
q->current_size -= 1;
return q;
}
int main(int argc, char *argv[]){
char *infile = NULL;
char buf[MAX_STR + 1];
FILE *fp = NULL;
Queue *q = NULL;
if (argc != 2) {
fprintf(stderr, "usage: %s inputfile\n", argv[0]);
exit(2);
}
infile = argv[1]; //入力ファイル名
//10行分保持するqueue
if ( (q = (Queue *)malloc(sizeof(Queue))) == NULL ) {
fprintf (stderr, "allocation error\n");
exit (2);
}
q->max_size = 10;
q->current_size = 0;
//ファイルから読み込んだ行をキューにいれる
fp = fopen(infile,"r");
while (fgets(buf, MAX_STR, fp)) {
q = enqueue(q,buf);
}
//キューから取り出し
while ((q = dequeue(q,buf)) != NULL) {
printf ("%s", buf);
}
return 0;
}