Tiny programs (C, C++, C#, ...)
File detail
Source code
/*
* Soubor: tail.c - implementace utility tail v ISO C99
* Kamil Dudka, FIT, DU2, priklad 1a, 17.4.2005
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <stdarg.h>
const unsigned long MaxLineLength = 1024 + 1; // 1024 znaku + znak zlomeni radku
const unsigned long DefaulLinesCount = 10;
/*
* Vlastni funkce, provadejici filtrovani streamu
*/
void tail (FILE *, unsigned long);
/*
* Funkce Error vytiskne chybove hlaseni na stderr a ukonci
* program s chybovym kodem 1. Pred chybovym hlasenim tiskne
* test "tail: ". Ma stejne parametry jako funkce printf.
*/
void Error(const char *fmt, ...);
/*
* Zavre soubor, pokud soubor neni stdin
*/
inline void closeInput (FILE *);
/*
* Funkce main nacte parametry a zavola funkci tail
*/
int main (int argc, char *argv[]) {
bool minusDetected = false;
unsigned long linesCount = DefaulLinesCount;
FILE *input = stdin;
// Cyklus postupne nacita parametry
for (int i=1; i<argc; i++) {
if (argv [i][0] == '-') {
// Pokud je prvni znak '-', pokusi se nacist cislo
if (argv [i][1] == '-')
Error ("Pocet radku musi byt kladny!");
if (minusDetected)
Error ("Duplicitni parametr!");
minusDetected = true;
if (1!= sscanf (argv[i]+1, "%lu", &linesCount))
Error ("Neplatny parametr!");
// Pokud neni prvni znak '-', pokusi se otevrit soubor
} else if (NULL==(input= fopen (argv[i],"r")))
Error ("Nelze otevrit vstupni soubor!");
}
// Zavola vlastni filtr
tail (input, linesCount);
// Po skonceni zavre vstupni soubor
closeInput (input);
return 0;
}
void Error(const char *fmt, ...) {
// Inicializace funkce s promennym poctem parametru
va_list pArgs;
va_start (pArgs, fmt);
// Vypis chybove hlasky na stderr
fprintf (stderr, "tail: ");
vfprintf (stderr, fmt, pArgs);
fprintf (stderr, "\n");
// Ukoncovaci makro funkce s promennym poctem parametru
va_end (pArgs);
// Shodi program s chybovym kodem 1
exit (1);
}
inline void closeInput (FILE *input) {
if (input != stdin)
fclose (input);
}
void tail (FILE *input, unsigned long linesCount) {
// Alokace bufferu potrebne velikosti na zasobniku
// Pozor - muze dojit preteceni zasobniku !!!
char fifo [linesCount][MaxLineLength+1];
unsigned long readed = 0;
unsigned long pos = 0;
// Cyklus nacita radky ze souboru a uklada je do bufferu fifo
for (; NULL!=fgets (fifo[pos], MaxLineLength+1, input); readed++, pos= readed%linesCount)
if (NULL== strstr (fifo [pos], "\n")) {
closeInput (input);
Error ("Prekrocena maximalni delka radku!");
}
if (readed < linesCount)
// Vypisou se vsechny radky, ketere byly nacteny
for (pos = 0; pos < readed; pos++)
fputs (fifo [pos], stdout);
else
// Vypise se poslednich linesCount radku
for (pos = 0; pos < linesCount; pos++)
fputs (fifo [(readed + pos) % linesCount], stdout);
}