/***************************************************************************** tail DESCRIPTION: tail prints the last -n lines of a input, if n is not give it prints 10 lines by default, no malloc or stcpy is used in this version and stack storage is allocated in the most efficent way for each line *****************************************************************************/ #include #include #include #define DEFAULT_N 10 #define MAXLEN 1000 #define MAXLINE 5000 #define BUFFSIZE MAXLEN * MAXLINE char buff[BUFFSIZE]; char *lineptr[MAXLINE]; int buff_now; int lineptr_now; int line_no; void get_tail(void); int sneed_getline(char str[], int max); void pr_tail(int nlines); int main(int argc, char **argv) { int nlines = 0; if (--argc == 1 && **(++argv) == '-' && isdigit(*++*argv)) { for (; isdigit(**argv) ; ++*argv) nlines = nlines * 10 + **argv - '0'; } else if (argc != 0) argc = -1; if (!nlines) nlines = DEFAULT_N; if ( argc >= 0 && nlines > 0 && nlines < MAXLINE) { get_tail(); pr_tail(nlines); } else printf("Usage: tail -n\n"); } void get_tail(void) { int len; while ((len = sneed_getline(buff + buff_now, MAXLEN)) > 0) { lineptr[lineptr_now] = buff + buff_now ; line_no++; buff_now = (buff_now + MAXLEN >= BUFFSIZE -1) ? 0 : buff_now + len + 1; lineptr_now = (lineptr_now >= MAXLINE - 1) ? 0 : lineptr_now + 1; } } void pr_tail(int nlines) { if (line_no < nlines) nlines = line_no; lineptr_now = (lineptr_now - nlines < 0) ? MAXLINE - 1 + lineptr_now - nlines : lineptr_now - nlines; while(nlines--) { printf("%s", lineptr[lineptr_now]); lineptr_now = (lineptr_now >= MAXLINE - 1) ? 0 : lineptr_now + 1; } } int sneed_getline(char str[], int max) { char input; char *str_og; str_og = str; --max; while (--max && (input = getchar()) != EOF && input != '\n') *str++ = input; if (input == '\n' && max) *str++ = input; *str = '\0'; return str - str_og; }