Program jako filtr v jazyce C

Z Milan Kerslager
Verze z 6. 4. 2009, 20:39, kterou vytvořil Milan.Kerslager (diskuse | příspěvky) (+kat)
(rozdíl) ← Starší verze | zobrazit aktuální verzi (rozdíl) | Novější verze → (rozdíl)
Přejít na: navigace, hledání

Programy, které zpracují vstup a vytvoří nějaký výstup se v unixových systémech obvykle programují jako filtry. Výhodou filtrů je možnost jejich spojování do kolon nebo přesměrování jeho vstupu či výstupu.

Filtr čte data ze standardního vstupu (stdin) a zapisuje na standardní výstup (stdout).

Filtr cat

Program cat je standardním nástrojem. Jeho zjednodušenou variantu si zkusíme naprogramovat. Úkolem programu je číst řádky ze vstupu a opisovat je na výstup. Program skončí v okamžiku, kdy je ukončen vstup. Všimněte si, že velikost bufferu je v programu nastavena pomocí definice BUFFSIZE. Tímto způsobem lze sjednotit velikost všech použitých bufferů a snadno centrálně změnit jejich velikost přepsáním jedné definice.

Vytvoříme soubor filtr.c:

#include <stdio.h>

#define BUFFSIZE 512

int main()
{
  char buffer[BUFFSIZE];

  while (fgets(buffer,BUFFSIZE,stdin) != NULL)
    puts(buffer);
  return 0;
}

Použití programu

Program přeložíme obvyklým způsobem. Po spuštění bez jakýchkoliv parametrů očekává program vstup z klávesnice. Po odeslání řádku klávesou Enter dojde k vypsání vloženého řádku na terminál. Ukončení vstupu lze provést stiskem kombinace kláves CTRL+d (označuje konec vstupu).

Program lze ale spustit i jinak. V následujícím příkladu je zadaný vstup zapsán do souboru soubor.txt (místo na terminál):

./filtr > soubor.txt

V následujícím příkladu vypíše program obsah souboru /etc/passwd na terminál:

./filtr < /etc/passwd

V následujícím příkladu vypíše program cat obsah souboru na standardní výstup, který je pomocí roury přesměrován do našeho filtru. Náš program filtr jen vstup opisuje na výstup, takže vstupující text bude beze změny vypsán na terminál (jako by tam filtr nebyl). Pokud bychom v našem programu naprogramovali nějakou změnu dat před jejich vypsáním, byl by obsah souboru příslušným způsobem uvnitř našeho filtru změněn.

cat /etc/passwd | ./filtr

Problém bufferu

Výše uvedený program má omezení, které vyplývá z velikosti použitého bufferu. Toto omezení nelze jednoduchým způsobem odstranit, protože předem nevíme, jak dlouhé budou vstupující řádky. Měli bychom ovšem počítat s tím, že při použití kódování UTF-8 jsou národní znaky kódovány do vícebajtových sekvencí, které představují jen 1 znak. To znamená, že v případě použití národních znaků bude maximální délka vstupujícího řádku menší, než při použití znaků z dolní poloviny ASCII tabulky.

Cvičení

Příklad 1
Napište program, který všechny načtené řádky napíše pozpátku, tj. začne znakem na konci vstupujícího řádku a skončí prvním znakem na řádku. Tuto činnost provede pro všechny vstupující řádky.
Příklad 2
Očíslujte řádky na výstupu.
Příklad 3
V případě, že bude uveden na řádku název souboru, program tento soubor načte a vypíše na standardní výstup. Umožněte, aby parametrů mohlo být více a všechny zadané soubory se vypsaly postupně bez jakéhokoliv vizuálního oddělení za sebou (tj. sloučení všech souborů).