また,明日学科の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; }