Program jako filtr v jazyce C: Porovnání verzí

Z Milan Kerslager
Přejít na: navigace, hledání
(Založení článku)
 
m (+kat)
 
(Nejsou zobrazeny 4 mezilehlé verze od stejného uživatele.)
Řádka 5: Řádka 5:
 
== Filtr cat ==
 
== 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. Vytvoříme soubor '''filtr.c''':
+
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.
  
#include <stdio.h>
+
Vytvoříme soubor '''filtr.c''':
+
 
#define BUFFSIZE 512
+
<source lang="c">
+
#include <stdio.h>
int main()
+
 
{
+
#define BUFFSIZE 512
  char buffer[BUFFSIZE];
+
 
+
int main()
  while (fgets(buffer,BUFFSIZE,stdin) != NULL)
+
{
    puts(buffer);
+
  char buffer[BUFFSIZE];
  return 0;
+
 
}
+
  while (fgets(buffer,BUFFSIZE,stdin) != NULL)
 +
    puts(buffer);
 +
  return 0;
 +
}
 +
</source>
  
 
=== Použití programu ===
 
=== Použití programu ===
Řádka 24: Řádka 28:
 
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 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:
+
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
 
  ./filtr > soubor.txt
  
Zadaný vstup je zapsán do souboru ''soubor.txt'' (místo na terminál).
+
V následujícím příkladu vypíše program obsah souboru ''/etc/passwd'' na terminál:
  
 
  ./filtr < /etc/passwd
 
  ./filtr < /etc/passwd
  
Program vypíše obsah souboru ''/etc/passwd'' na terminál.
+
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
 
  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í ==
 
== Cvičení ==
  
=== Příklad 1 ===
+
;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.
  
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 2 ===
+
;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ů).
  
Očíslujte řádky na výstupu.
+
[[Kategorie:Jazyk C v Linuxu]]

Aktuální verze z 6. 4. 2009, 20:39

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ů).