Program jako filtr v jazyce C

Z Milan Kerslager
Verze z 22. 5. 2008, 11:07, kterou vytvořil Milan.Kerslager (diskuse | příspěvky) (Rozšíření)
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:

./filtr > soubor.txt

Zadaný vstup je zapsán do souboru soubor.txt (místo na terminál).

./filtr < /etc/passwd

Program vypíše obsah souboru /etc/passwd na terminál.

cat /etc/passwd | ./filtr

Program cat vypíše 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.

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.