|
Nutno vzpomenout na dobu, kdy jsme psali programy na papír a pak je děrovali či nechávali děrovat do štítků nebo pásek, když narážíme na problémy se soubory a operace s nimi. Údajně jedním z důvodů, proč se PC tak rychle rozšířila v podnikové sféře, byla možnost na monitoru editovat textové soubory, uchovávat, kopírovat je a tisknout.
Druhy souborů se od sebe liší. Každý z nás zná textové soubory. Používáme je nejen na psaní milostné korespondence, ale i na psaní essayeů či jiných školních úkolů nebo pracovních zpráv atd. Textovými soubory jsou i zdrojové texty počítačových programů nebo html‑stránky.
Další soubory, které neustále na počítačích používáme, aniž si to zhusta uvědomujeme, jsou „vykonatelné” soubory ‑ exec(utable) files. Ty se liší podle OS a jejich zavaděčů. Nahrání těchto souborů do vnitřní paměti počítače a následné předání řízení do ní je spuštění programů. Těmto programům se někdy říká binární, v programátorském žargonu binárka.
Další druh souborů, které jsme dosud možná nepoužívali, jsou soubory datové.
Ikdyž to neplatí absolutně,
jejich porce dat ‑ záznamy ‑ jsou
pevné délky a umožňují nám se v těchto souborech rychle
„pohybovat” ‑ zpracovávat je s mnohem menším
zdržovaním jejich procházením a analýzou. V jazyce C je takovou
porcí dat datová struktura struct
.
V programech při některých manipulacích se soubory používáme stejné operace
bez ohledu na to, který druh souboru to je.
Jsou to zejména
stdio.h
jakožto typ FILE
FILE
FILE *f;
fopen(const char *fname, const char *mode)
přiřazuje příslušné proměnné otevřený souborfname
‑ je jméno souboru,
případně úplné i. e. včetně cesty (path
)mode
‑ určuje způsob, jak bude soubor použit:
soubor | "r" | "r+" | "w" | "w+" | "a" | "a+" |
---|---|---|---|---|---|---|
nemusí už existovat | ||||||
stejně pojmenovaný není ztracen | ||||||
lze z něj číst | ||||||
lze do něj zapisovat kdekoli | ||||||
lze zapisovat na jeho konec |
f = fopen("nejakySoubor", "r");
NULL
.rewind
a fseek
.fclose(FILE *stream)
uzavírá otevřený souborstream
‑ je proměnná typu soubor fclose(f);
rename(const char *oldname, const char *newname)
,
kde jsou oba parametry ‑ (znakové) řetězce ‑ jsou jména souborů v prvním případě původní
ve druhém nové. Funkce rename
(zřejmé podle jména) soubory přejmenovává.remove(const char *fname)
s jediným parametr ‑ (znakový) řetězec ‑ jménem souboru.
Funkce remove(const char *fname)
soubor s tímto jménem smaže.
Pro něj již známe fgets
,
jen místo stdin
použijeme příslušný (a otevřený soubor).
fgets
nám ohlídá i konec souboru.
Místo printf
a scanf
můžeme používat
fprintf
a fscanf
s parametrem typu soubor
(FILE *
) navíc.
Jazyk C vznikal pod OS Unix a dodnes je mu v lecčems poplatný.
Protože Bill Gates (Microsoft) záškodnicky zaměnil unixovský přechod na nový řádek
dvěma znaky, tak nám hrozí problémy (přinejmenším komplikace). Původně se textové soubory
ukládaly odlišně od datových. U textových se k módu (mode) přidával suffix 't'.
A ikdyž to už neplatí: používejte ho, pokud si nejste nastopro jistí, že máte textový
režim nastavený implicitně, pro použití neunixových textových souborů.
(Pak se ony přechody na nový řádek patřičně překódují.)
(Těsně před koncem textového souboru má být právě jeden přechod na nový řádek.
Používáte-li ‑ přes všechna varování ‑ MS winDOS,
pak si zapněte zobrazování „Přípony názvů souborů” (ve Správci souborů -> Zobrazení a v prostředním sloupci [] zakliknout))
Program
/** * Funkce pro ukazku cteni ze souboru * * @file fileATesting.c * @author Ales Zlamal */ #include <stdlib.h> #include <stdio.h> #define LINE_LENGTH 128 int main() { FILE *f; char line[LINE_LENGTH]; if ((f = fopen("testingFile.txt", "r")) == NULL) { printf("Nepodarilo se otevrit soubor \"testingFile.txt\"\n"); return EXIT_FAILURE; } while (fgets(line, LINE_LENGTH, f) != NULL) { printf(">>> %s", line); *(line + 4) = '/'; printf(">>> %s\n", line); } printf("konec\n"); fclose(f); return EXIT_SUCCESS; }
testingFile.txt
:ABCDEFGHIJKLMN BCDEFGHIJKLMNA CDEFGHIJKLMNAB DEFGHIJKLMNABC EFGHIJKLMNABCD FGHIJKLMNABCDE
>>> ABCDEFGHIJKLMN >>> ABCD/FGHIJKLMN >>> BCDEFGHIJKLMNA >>> BCDE/GHIJKLMNA >>> CDEFGHIJKLMNAB >>> CDEF/HIJKLMNAB >>> DEFGHIJKLMNABC >>> DEFG/IJKLMNABC >>> EFGHIJKLMNABCD >>> EFGH/JKLMNABCD >>> FGHIJKLMNABCDE >>> FGHI/KLMNABCDE konec
vyskaAVahaOsob.txt
obsahujících jméno či jména osob, jejich výšku v cm a váhu v kg a z nich spočítat
jejich BMI (body mass index) a vytisknout tyto údaje se znakem '+'
u těch, kteří překračují průměrnou hodnotu BMI osob v souboru do dalšího textového souboru vyskaVahaABMIOsob.txt
.
Hodnoty z již zpracovaných řádků neukládejte.vyskaAVahaOsob.txt
:
Maxim Kaspar Jura 177 84 Adam Kopyto 182 82 Anna Marie Purtnova 168 58 Julie Mamaspar 164 55 Marketa Lulova 170 60 Efraim Bripino 179 75
vyskaVahaABMIOsob.txt
:
Maxim Kaspar Jura 177 84; BMI = 26.8 + Adam Kopyto 182 82; BMI = 24.8 + Anna Marie Purtnova 168 58; BMI = 20.5 Julie Mamaspar 164 55; BMI = 20.4 Marketa Lulova 170 60; BMI = 20.8 Efraim Bripino 179 75; BMI = 23.4 +
se do jisté míry chovají jako pole záznamů (datových struktur) ‑ jen nám
(nezapomeneme-li zavřít soubor s nimi) zůstane i po skončení programu.
Používat pro ně můžeme funkce fread
,
fwrite
, rewind
,
fseek
, a ftell
.
fread(adresaPromenneTohoNejakehoTypu, sizeof(nejakyTyp), 1, f);
fwrite(adresaPromenneTohoNejakehoTypu, sizeof(nejakyTyp), 1, f);
S těmito funkcemi ale bude problém indikovat konec souboru. Nepoužívejte konstantu EOF.
Mohou s ní být problémy a ve skutečnosti v souborech už není (jak kdysi bývala).
Teď ji generuje runtime support (podpora při běhu), ale problémy zůstaly.
Používejte funkci feof
.