• Vstup z textového souboru c. Práce se soubory v jazyce C

    Práce s textovými soubory v C++.

    Existují dva hlavní typy souborů: textové a binární. Soubory umožňují uživateli číst velké množství dat přímo z disku, aniž by je musel zadávat z klávesnice.

      Text se nazývají soubory skládající se z libovolných znaků. Jsou uspořádány do řádků, z nichž každý končí znakem konce řádku. Samotný konec souboru je označen symbolem "konec souboru". Při zápisu informací do textového souboru, který lze zobrazit pomocí libovolného textového editoru, jsou všechna data převedena do znakového typu a uložena ve znakové podobě.

      V binární V souborech se informace čtou a zapisují ve formě bloků určité velikosti, do kterých lze ukládat data libovolného druhu a struktury.

    Chcete-li pracovat se soubory, speciální typy dat, volal proudy. Tok ifstream se používá pro práci se soubory v režimu čtení a outstream v režimu nahrávání. Proud se používá pro práci se soubory v režimu zápisu i čtení. fstream.

    V programech C++ je při práci s textovými soubory nutné zahrnout knihovny iostream a fstream.

    V následujících situacích zapsat data do textového souboru, musíte:

      popsat proměnnou typu stream.

      výstupní informace do souboru.

      nezapomeňte soubor zavřít.

    Pro čtení data z textového souboru, musíte:

      popsat proměnnou typu ifstream.

      otevřít soubor pomocí funkce otevřít.

      zavřete soubor.

    Záznam informace do textového souboru

      Jak již bylo zmíněno dříve, abyste mohli začít pracovat s textovým souborem, musíte deklarovat proměnnou typu ofstream. Například takto:

      Vytvoří se proměnná F pro zápis informací do souboru.

      Dalším krokem je otevření souboru pro zápis. Obecně bude operátor otevření streamu vypadat takto:

    F. otevřít("soubor", režim);

    Zde F je proměnná deklarovaná jako ofstream,

    soubor - celý název souboru na disku,

    režim - režim práce s otevřeným souborem.

    Vezměte prosím na vědomí, že při zadávání celého názvu souboru musíte zadat dvojité lomítko. Například celý název souboru noobs.txt umístěného ve složce hry na disku D: bude muset být zapsán takto:

    D:\\hra\\noobs.txt.

    Soubor lze otevřít v jednom z následujících režimů:

    ios::in - otevřít soubor v režimu čtení dat, tento režim je výchozí režim pro streamy ifstream;

    ios::out - otevřít soubor v režimu zápisu dat (v tomto případě jsou zničeny informace o existujícím souboru), tento režim je výchozí režim pro streamy proudu;

    ios::app - otevření souboru v režimu zápisu dat na konec souboru;

    ios::ate - přesun na konec již otevřeného souboru;

    ios::trunc - vymažte soubor, totéž se stane v režimu ios::out;

    ios::nocreate - neotevírat soubor, pokud neexistuje;

    ios::noreplace - Neotevírejte existující soubor.

    Parametr mode může chybět, v takovém případě se soubor otevře ve výchozím režimu pro tento stream.

    Po úspěšném otevření souboru (v libovolném režimu) bude proměnná F ukládat true, jinak false. Tím se zkontroluje správnost operace otevření souboru.

    Soubor můžete otevřít (vezměme si jako příklad D:\\game\\noobs.txt) v režimu zápisu pomocí jedné z následujících metod:

    // První cesta

    offstream F;

    F.open("D:\\hra\\noobs.txt", ios::out);

    //druhý způsob, režim ios::out je výchozí režim

    // Pro tokoutstream

    offstream F;

    //třetí způsob kombinuje popis proměnné a typ streamu

    //a otevřete soubor v jednom příkazu

    ofstream F("D:\\hra\\noobs.txt", ios::out);

    Po otevření souboru v režimu zápisu se vytvoří prázdný soubor, do kterého lze zapisovat informace.

    Pokud chcete otevřít existující soubor v režimu předběžného zápisu, použijte jako režim ios::app.

    Po otevření souboru v režimu zápisu do něj můžete zapisovat stejným způsobem jako na obrazovce, pouze místo standardního výstupního zařízenícoutmusíte zadat název otevřeného souboru.

    Například pro zápis proměnné a do streamu F by výstupní příkaz byl:

    Chcete-li sekvenční tisk proměnných b, c, d do proudu G, výstupní příkaz bude:

    G<

    Stream je uzavřen pomocí operátoru:

    PŘÍKLAD:

    Vytvořte textový soubor D:\\hra\\noobs.txt a napište do něj n reálných čísel.

    #include "stdafx.h"

    #zahrnout

    #zahrnout

    #zahrnout

    pomocí jmenného prostoru std;

    int main()

    setlocale(LC_ALL, "RUS");

    int i, n;

    dvojité a;

    //popisuje proud pro zápis dat do souboru

    outstream F;

    //otevřít soubor v režimu zápisu,

    //režimios:: venve výchozím nastavení nainstalováno

    f.open("D:\\hra\\noobs.txt", ios::out);

    //zadejte počet reálných čísel

    cout<<" n="; cin>> n;

    //smyčka pro zadávání reálných čísel

    //a zapsat je do souboru

    pro (i=0; i

    cout<<"a=";

    //zadejte číslo

    cin >>a;

    F<

    //uzavření streamu

    f.close();

    system("pauza");

    návrat 0;

    _______________________________________________________________

    Aby bylo možné číst informace z textového souboru, je nutné deklarovat proměnnou typu ifstream. Poté musíte soubor otevřít pro čtení pomocí operátoru OTEVŘENO. Pokud se proměnná nazývá F, pak první dva příkazy budou následující:

    F.open("D:\\hra\\noobs.txt", ios::in);

    Po otevření souboru v režimu čtení z něj můžete číst informace stejným způsobem jako z klávesnice, jen místo tohocinzadejte název proudu, ze kterého se budou data číst.

    Chcete-li například číst z proudu F do proměnné a, příkaz input by vypadal takto:

    Dvě čísla v textovém editoru jsou považována za oddělená, pokud je mezi nimi alespoň jeden ze znaků: mezera, tabulátor, znak konce řádku. Je dobré, když programátor předem ví, kolik a jaké hodnoty má uložit do textového souboru. Typ hodnot uložených v souboru je však často jednoduše znám a jejich počet se může lišit. Chcete-li tento problém vyřešit, musíte číst hodnoty ze souboru jednu po druhé a před každým čtením zkontrolovat, zda byl dosažen konec souboru. Existuje na to funkce F. eof().

    Zde F je název proudu, funkce vrací booleovskou hodnotu: true nebo false, podle toho, zda bylo dosaženo konce souboru. Smyčku pro čtení obsahu celého souboru lze tedy zapsat takto:

    //uspořádání pro čtení hodnot ze souboru, spuštění

    //cyklus se přeruší, když se dostaneme na konec souboru,

    //v tomto případě F.eof() vrátí true

    zatímco (!F.eof())

    PŘÍKLAD:

    Reálná čísla jsou uložena v textovém souboru D:\\hra\\noobs.txt, zobrazte je na obrazovce a vypočítejte jejich počet.

    #include "stdafx.h"

    #zahrnout

    #zahrnout

    #zahrnout

    #zahrnout

    pomocí jmenného prostoru std;

    int main()

    setlocale(LC_ALL, "RUS");

    intn=0;

    plovák a;

    fstream F;

    //otevřít soubor v režimu čtení

    F.open("D:\\hra\\noobs.txt");

    //pokud byl soubor otevřen správně, pak

    //smyčka pro čtení hodnot ze souboru; provádění smyčky bude přerušeno,

    //když se dostaneme na konec souboru, v takovém případě F.eof() vrátí true.

    zatímco (!F.eof())

    //načtení další hodnoty z proudu F do proměnné a

    F>>a;

    //vypíše hodnotu proměnné a na obrazovku

    cout<

    //zvýší počet přečtených čísel

    //uzavření streamu

    f.close();

    //zadání počtu přečtených čísel na obrazovce

    cout<<"n="<

    //pokud byl soubor otevřen nesprávně, pak výstup

    //zprávy o absenci takového souboru

    jinak cout<<" Файл не существует"<

    system("pauza");

    návrat 0;

    C++. Zpracování binárních souborů

    Při zápisu informací do binárního souboru se znaky a čísla zapisují jako sekvence bajtů.

    V následujících situacích zapsat data do binárního souboru, potřebujete:

      deklarovat proměnnou souboru typu FAIL * pomocí příkazu FILE *název souboru;. Zde název_souboru je název proměnné, kde bude uložen ukazatel na soubor.

      zapisovat informace do souboru pomocí funkce fwrite

    V následujících situacích myslet si z data z binárního souboru, musíte:

      popsat proměnnou typu FILE *

      otevřít soubor s funkcí fopen

      zavřít soubor funkcí fclose

    Základní funkce potřebné pro práci s binárními soubory.

    Pro objevy soubor, je určena funkce fopen.

    FILE *fopen(const *název souboru, const char *režim)

    Zde název_souboru je řetězec, který ukládá celé jméno otevíraného souboru, mode je řetězec, který definuje režim práce se souborem; jsou možné následující hodnoty:

    "rb" - otevření binárního souboru v režimu čtení;

    "wb" - vytvoří binární soubor pro zápis; pokud existuje, jeho obsah je vymazán;

    "ab" - vytvořit nebo otevřít binární soubor pro připojení na konec souboru;

    "rb+" - otevře existující binární soubor v režimu čtení a zápisu;

    "wb+" - otevření binárního souboru v režimu čtení-zápis, existující soubor je vymazán;

    "ab+" - Binární soubor je otevřen nebo vytvořen pro opravu existujících informací a přidání nových informací na konec souboru.

    Funkce vrátí hodnotu NULL v proměnné souboru f, pokud soubor nebyl úspěšně otevřen. Po otevření souboru je k dispozici jeho 0. bajt, ukazatel souboru je 0, jehož hodnota je při čtení nebo zápisu posunuta o přečtený (zapsaný) počet bajtů. Aktuální hodnota ukazatele souboru je číslo bajtu, ze kterého bude probíhat operace čtení nebo zápisu.

    Pro zavírání soubor, je určena funkce fclose

    int fclose(FILE *název souboru);

    Vrátí 0, pokud byl soubor úspěšně uzavřen, jinak NULL.

    Funkce odstranění je pro odstranění soubory.

    int remove(const char *název souboru);

    Tato funkce odstraní soubor s názvem filenema z disku. Soubor, který má být odstraněn, musí být uzavřen. Pokud soubor nelze odstranit, funkce vrátí nenulovou hodnotu.

    Pro přejmenování soubory, funkce přejmenování je určena:

    int rename(const char *starýsoubor, const char *novýfilename);

    První parametr je starý název souboru, druhý je nový. Vrátí 0 po úspěšném dokončení programu.

    Čtení z binárního souboru se provádí pomocí funkce fread:

    fread(void *ptr, velikost, n, FILE *název souboru);

    Funkce fread načte n prvků velikosti size z názvu souboru do pole ptr. Funkce vrací počet přečtených prvků. Po načtení ze souboru se jeho ukazatel posune o n*velikost bytů.

    Záznam do binárního souboru se provádí pomocí funkce fwrite:

    fwrite(const void *ptr, velikost, n, FILE *název souboru);

    Funkce fwrite zapíše n prvků velikosti size do názvu souboru z pole ptr. Funkce vrací počet zapsaných prvků. Po zapsání informace do souboru se ukazatel posune o n*velikost bajtů.

    Pro kontrola konce souboru existuje funkce feof:

    int feof(FILE *název souboru);

    Pokud je dosaženo konce souboru, vrátí nenulovou hodnotu.

    PŘÍKLAD:

    Vytvořte binární soubor D:\\game\\noobs.dat a napište do něj celé číslo n a n reálných čísel.

    #include "stdafx.h"

    #zahrnout

    pomocí jmenného prostoru std;

    int main()

    setlocale(LC_ALL, "RUS");

    int n, i;

    dvojité a;

    // vytvoření binárního souboru v režimu zápisu

    f=fopen("D:\\hra\\noobs.dat", "wb");

    // vstup číslan

    cout<<"n="; cin>>n;

    fwrite(&n, sizeof(int), 1, f);

    //smyčka pro zadání n reálných čísel

    pro (i=0; i

    //zadejte další reálné číslo

    cout<<"a=";

    cin >>a;

    //zapíše reálné číslo do binárního souboru

    fwrite(&a, sizeof(double), 1, f);

    // zavřít soubor

    fclose(f);

    system("pauza");

    návrat 0;

    PŘÍKLAD:

    Zobrazte obsah binárního souboru D:\\game\\noobs.dat vytvořeného v předchozí úloze

    #include "stdafx.h"

    #zahrnout

    pomocí jmenného prostoru std;

    int main()

    setlocale(LC_ALL, "RUS");

    int n, i;

    dvojité *a;

    SOUBOR *f; //popište proměnnou souboru

    //otevření existujícího binárního souboru v režimu čtení

    //přečte jedno celé číslo ze souboru do proměnné n

    //výstup n na obrazovku

    cout<<"n="<

    //přidělí paměť pro pole n čísel

    a=new double[n];

    //načtení n reálných čísel ze souboru do pole a

    //vypíše pole na obrazovku

    pro (i=0; i

    cout<

    cout<

    // zavřít soubor

    fclose(f);

    system("pauza");

    návrat 0;

    Binární- sekvenční datová struktura, po otevření souboru je k dispozici první bajt v něm uložený. Můžete postupně zapisovat nebo číst data ze souboru. Předpokládejme, že potřebujete spočítat patnácté číslo a pak první. Se sériovým přístupem to lze provést následujícím způsobem:

    int n, i;

    dvojité a;

    SOUBOR *f;

    f=fopen("D:\\hra\\noobs.dat", "rb");

    pro (i=0; i<15; i++)

    fclose(f);

    f=fopen("D:\\hra\\noobs.dat", "rb");

    fread(&a, sizeof(double), 1, f);

    fclose(f);

    Jak vidíte, čtení čísel ze souboru a následné znovuotevření souboru není nejpohodlnější způsob. Pro přesunutí ukazatele souboru na daný bajt je mnohem pohodlnější použít funkci fseek.

    int fseek(FILE *název souboru, dlouhý int offset, int původ);

    Funkce nastaví ukazatel na aktuální pozici souboru F v souladu s hodnotou počátku a offsetu. Parametr offset se rovná počtu bajtů, o které bude ukazatel souboru posunut vzhledem k počátku určenému parametrem počátku. Hodnota parametru počátku musí být jedna z následujících hodnot pro offset definovaných v záhlaví stdio.h:

    SEEK_SET - od začátku souboru;

    SEEK_CUR - z aktuální pozice;

    SEEK_END – od konce souboru.

    Funkce vrátí nulu, pokud je operace úspěšná, nenulovou, pokud se posun nezdaří.

    Funkce fseek ve skutečnosti implementuje přímý přístup k jakékoli hodnotě v souboru. Potřebujete pouze znát umístění (číslo bajtu) hodnoty v souboru. Zvažte použití přímého přístupu v binárních souborech pomocí příkladu řešení následujícího problému.

    PŘÍKLAD

    V dříve vytvořeném binárním souboru D:\\game\\noobs.dat zaměňte největší a nejmenší z reálných čísel.

    Algoritmus pro řešení problému se skládá z následujících kroků:

      čtení reálných hodnot ze souboru do pole a.

      vyhledejte v poli a maximální (max) a minimální (min) hodnoty a jejich čísla (imax, imin).

      posunutí ukazatele souboru na maximální hodnotu a zápis min.

      přesunutí ukazatele souboru na minimální hodnotu a zápis max.

    Níže je text programu pro řešení problému s komentáři.

    #include "stdafx.h"

    #zahrnout

    pomocí jmenného prostoru std;

    int main()

    setlocale(LC_ALL, "RUS");

    int n, i, imax, imin;

    double *a, max, min;

    SOUBOR *f;

    //otevřít soubor v režimu čtení/zápisu

    f=fopen("D:\\hra\\noobs.dat", "rb+");

    //čtení ze souboru do proměnné n číslo

    //skutečná čísla v souboru

    fread(&n, sizeof(int), 1, f);

    cout<<"n="<

    //přidělení paměti pro ukládání reálných čísel,

    //které bude uloženo v poli a

    a=new double[n];

    //čtení ze souboru do pole a reálných čísel

    fread(a, sizeof(double), n, f);

    //hledá maximální a minimální prvky

    //v poli a a jejich indexy

    pro (imax=imin=0, max=min=a, i=1; i

    if (a[i]>max)

    max=a[i];

    pokud (a[i]

    min=a[i];

    // pohybující se ukazatel Na maximum živel

    fseek(f, sizeof(int)+imax*sizeof(double), SEEK_SET);

    //záznam min místo maximálního prvku souboru

    fwrite(&min, sizeof(double), 1, f);

    // pohybující se ukazatel Na minimální živel

    fseek(f, sizeof(int)+imin*sizeof(double), SEEK_SET);

    //záznam max místo minimálního prvku souboru

    fwrite(&max, sizeof(double), 1, f);

    //uzavření souboru

    fclose(f);

    // volná paměť

    vymazat[ ]A;

    system("pauza");

    Tato část se bude zabývat dvěma způsoby práce se soubory a standardní třídou MFC CFileDialog.


    1. Práce se soubory v C (funguje i v C++)..


      #zahrnout
      #zahrnout

    Void main(void)
    {
    SOUBOR *soubor;
    char* název_souboru = "soubor.txt";
    charload_string = "žádný";

    Soubor = fopen(název_souboru, "w");

    Fputs("řetězec", soubor);

    Soubor = fopen(název_souboru, "r");
    if(soubor != 0)
    {
    fgets(načíst_řetězec, 50 , soubor);
    střih)
    jiný
    {
    střih)
    fclose(soubor);
    ) Popis funkcí práce se soubory je v knihovně stdio.h
    Nejprve musíte vytvořit ukazatel na proměnnou typu FILE ( FILE* soubor;).
    Otevření souboru se provede voláním funkce fopen ( soubor = fopen(název_souboru, "w");)
    První parametr této funkce je název souboru, druhý udává, v jakém režimu se má soubor otevřít. "w"- otevřít pro nahrávání, "r"- otevřeno pro čtení, "A"- přidávání souborů (toto jsou nejpoužívanější režimy, i když existují i ​​jiné). Zápis a čtení dat ze souboru se provádí pomocí následujících funkcí: fputc, fputs, fgetc, fgets, fprintf, fscanf(Popis těchto funkcí viz stdio.h).
    Uzavření souboru se provede voláním funkce fclose ( fclose(soubor);).

    Práce se soubory pomocí MFC (třídy CFile, CStdioFile, ...) a standardní MFC třídy CFileDialog.


    Knihovna MFC obsahuje několik tříd pro zpracování souborů. Třídy popsané níže jsou zděděny ze základní třídy

    CFile.

    Třída CF ile

    CFilenavržený pro práci se soubory. Zjednodušuje použití souborů tím, že soubor představuje jako objekt, který lze vytvářet, číst, zapisovat a tak dále.

    Chcete-li získat přístup k souboru, musíte nejprve vytvořit objekt třídy CFile. Konstruktor třídy umožňuje otevřít soubor ihned po vytvoření takového objektu. Pomocí této metody však můžete soubor otevřít později

    OTEVŘENO.

    Otevírání a vytváření souborů

    Po vytvoření objektu třídy CFilesoubor můžete otevřít voláním metodyOTEVŘENO. Metoda musí specifikovat cestu k souboru, který má být otevřen, a způsob jeho použití. Prototyp metodyOTEVŘENOmá následující podobu:

    Virtual BOOL Open(LPCTSTR lpszFileName, UINT nOpenFlags, CFileException* pError=NULL);

    Parametr lpszFileName musí být název souboru, který se má otevřít. Můžete zadat pouze název souboru nebo úplný název souboru, včetně úplné cesty k němu.

    Druhý parametr, nOpenFlags, určuje akci, kterou metoda Open se souborem provede, a také atributy souboru. Níže jsou uvedeny některé možné hodnoty parametru nOpenFlags:

    • CFile::modeCreate - Vytváří se nový soubor. Pokud zadaný soubor existuje, jeho obsah se vymaže a délka souboru se nastaví na nulu.
    • CFile::modeNoTruncate – Tento soubor je určen k použití ve spojení se souborem CFile::modeCreate. Pokud je vytvořen již existující soubor, jeho obsah nebude smazán.

  • CFile::modeRea d - Soubor je otevřen pouze pro čtení.
  • CFile::modeReadWrite - Soubor je otevřen pro zápis a pro čtení.
  • CFile::modeWrite - Soubor je otevřen pouze pro zápis.
  • CFile::typeText – Používá se třídami odvozenými od třídy CFile, jako je CStdioFile, pro práci se soubory v textovém režimu. Textový režim převádí kombinaci návratu vozíku a posunu řádku.
  • CFile::Binary – používá se třídami odvozenými od třídy CFile, jako je CStdioFile, k práci se soubory v binárním režimu.
  • Volitelný parametr pError, což je ukazatel na objekt třídy CFileException, se používá pouze v případě, že by provedení operace se souborem způsobilo chybu. V tomto případě budou další informace zapsány do objektu, na který ukazuje pError.

    Metoda OTEVŘENOvrátí nenulovou hodnotu, pokud je soubor otevřený a nulu při chybě. Při otevírání souboru může dojít k chybě, například pokud je v metodě Open pro čtení zadán neexistující soubor.

    Otevřít ID souboru

    Třída CFile zahrnuje datový člen m_hFile typu UINT. Ukládá ID otevřeného souboru. Pokud byl objekt třídy CFile již vytvořen, ale soubor ještě nebyl otevřen, pak se do proměnné m_hFile zapíše konstanta hFileNull.

    Obvykle se ID otevřeného souboru nepoužívá přímo. Třídní metody CFileumožňují provádět se soubory téměř jakoukoli operaci a nevyžadují zadání identifikátoru souboru. Protože m_hFile je členem třídy, implementace jeho metod k němu má vždy volný přístup.

    Zavírání souborů

    Po ukončení práce se souborem je nutné jej uzavřít. Třída CFilemá k tomu speciální metodu Close. Je třeba poznamenat, že pokud byl vytvořen objekt třídy CFile a je otevřen soubor a poté je objekt smazán, pak je soubor s ním spojený automaticky uzavřen pomocí destruktoru.

    Čtení a zápis souborů

    Existuje několik metod třídy pro přístup k souborům. CFile: Číst, číst obrovské, psát, psát obrovské, splachovat. Metody Číst a číst obrovské navržený pro čtení dat z dříve otevřeného souboru. Na 32bitových operačních systémech mohou obě metody současně číst více než 65535 bajtů ze souboru. Specifikace ReadHuge byla zastaralá a je zachována pouze kvůli kompatibilitě s 16bitovými operačními systémy.

    Data načtená ze souboru se zapisují do vyrovnávací paměti lpBuf. Parametr nCount určuje počet bajtů ke čtení ze souboru. Ve skutečnosti lze ze souboru přečíst méně bajtů, než požaduje parametr nCount. K tomu dojde, pokud je při čtení dosaženo konce souboru. Metody vrací počet bajtů přečtených ze souboru.

    Metody Write a WriteHuge jsou určeny pro zápis do souboru. Na 32bitových operačních systémech mohou obě metody zapsat do souboru více než 65535 bajtů současně. Methods zapíše nCount bajtů z vyrovnávací paměti lpBuf do otevřeného souboru. Pokud dojde k chybě zápisu, jako je například plný disk, metoda vyvolá zpracování výjimek.

    Proplachovací metoda

    Když se k zápisu dat na disk používá metoda Write nebo WriteHuge, může chvíli trvat, než se bude nacházet v dočasné vyrovnávací paměti. Abyste se ujistili, že jsou v souboru na disku provedeny potřebné změny, musíte použít metodu Flush.

    Operace se soubory

    Třída zahrnuje metody, které umožňují provádět různé operace se soubory, jako je kopírování, přejmenování, mazání, změna atributů.

    Chcete-li změnit název souboru, třída CFile obsahuje statickou metodu PřejmenovatTen plní funkce tohoto příkazu. Metodu nelze použít k přejmenování adresářů. Pokud dojde k chybě, metoda vyvolá výjimku.

    Pro mazání souborů ve třídě CFile je zahrnuta statická metoda OdstranitA, která vám umožní odstranit zadaný soubor. Tato metoda neumožňuje mazat adresáře. Pokud soubor nelze odstranit, metoda vyvolá výjimku.

    Pro určení data a času vytvoření souboru, jeho délky a atributů, statická metoda získat stav. Existují dva druhy metod - první je definována jako virtuální metoda a druhá je definována jako statická metoda.

    Virtuální verze metody získat stavdefinuje stav otevřeného souboru přidruženého k tomuto objektu CFile. Tato metoda je volána pouze v případě, že byl vytvořen objekt CFile a soubor je otevřen.

    Statická verze metody získat stavumožňuje určit vlastnosti souboru, který není přidružen k objektu třídy CFile. Chcete-li použít tuto metodu, nemusíte soubor nejprve otevírat.

    blokování

    Metody zahrnuté ve třídě rozsah zámku A odemknout rozsah, které vám umožňují uzamknout jeden nebo více datových souborů před přístupem z jiných procesů. Pokud se aplikace pokusí znovu uzamknout data, která byla dříve uzamčena touto nebo jinou aplikací, je vyvolána výjimka. Zámek je jedním z mechanismů, který umožňuje více aplikacím nebo procesům pracovat na stejném souboru současně, aniž by se navzájem rušily.

    Pomocí této metody můžete nastavit zámek rozsah zámku. Chcete-li odstranit nainstalované zámky, musíte použít metoduodemknout rozsah. Pokud je v jednom souboru nastaveno několik zámků, musí být každý z nich odstraněn samostatným voláním metodyodemknout rozsah.

    Polohování

    Chcete-li přesunout ukazatel aktuální pozice souboru na novou pozici, můžete použít jednu z následujících metod třídy CFile - Seek, SeekToBegin, SeekToEnd. Do třídy CFilezahrnuje také metody, které umožňují nastavit a změnit délku souboru, -GetLength, SetLength.

    Při otevření souboru se ukazatel aktuální pozice souboru nachází na samém začátku souboru. Když je část dat čtena nebo zapisována, ukazatel aktuální pozice se přesune ke konci souboru a ukazuje na data, která budou čtena nebo zapisována při další operaci čtení nebo zápisu do souboru.

    Chcete-li přesunout ukazatel aktuální polohy souboru na libovolné místo, můžete použít obecnou metodu

    Hledat. Umožňuje posunout ukazatel o určitý počet bajtů vzhledem k začátku, konci nebo aktuální pozici ukazatele.

    Chcete-li přesunout ukazatel na začátek nebo konec souboru, je nejvhodnější použít speciální metody. Metoda

    SeekToBeginpřesune ukazatel na začátek souboru a metoduSeekToEnd- na jeho konci.

    Ale pro určení délky otevřeného souboru není nutné přesouvat jeho ukazatel. Můžete použít metodu

    GetLength. Tato metoda také vrátí délku otevřeného souboru v bajtech. MetodaSetLengthumožňuje změnit délku otevřeného souboru. Pokud tato metoda zvětší velikost souboru, pak hodnota posledních bajtů není definována.

    Pomocí této metody lze určit aktuální polohu ukazatele souboru

    GetPosition. Vráceno metodouGetPosition32bitová hodnota určuje posun ukazatele od začátku souboru.

    Charakteristika otevřeného souboru

    Chcete-li určit umístění otevřeného souboru na disku, musíte zavolat metodu GetFilePath. Tato metoda vrací objekt třídyCString, který obsahuje úplnou cestu k souboru, včetně názvu jednotky, adresářů, názvu souboru a přípony souboru.

    Pokud chcete pouze určit název a příponu otevřeného souboru, můžete použít metodu GetFileName. Vrací objekt CString obsahující název souboru. V případě, že potřebujete zjistit pouze název otevřeného souboru bez přípony, použijte metoduGetFileTitle.

    Následující metoda třídy CFile umožňuje nastavit cestu k souboru. Tato metoda nevytváří, nekopíruje ani nemění název souboru, pouze vyplní odpovídající datový prvek v objektu třídy CFile.

    třída C

    memfile

    Knihovna MFC zahrnuje třídu

    CMemFile, zděděné ze základní třídyCFile. Třída CMemFilepředstavuje soubor alokovaný v paměti RAM. S objekty třídyCMemFilestejně jako u objektů třídyCFile. Rozdíl je v tom, že soubor přidružený k objektuCMemFile, není umístěn na disku, ale v paměti RAM počítače. Díky tomu jsou operace s takovým souborem mnohem rychlejší než s běžnými soubory.

    Práce s objekty třídy

    CMemFile, můžete použít téměř všechny metody třídyCFilekteré byly popsány výše. Do takového souboru můžete zapisovat data nebo je číst. Kromě těchto metod je třCMemFilevčetně dalších metod.

    Existují dva různé konstruktory pro vytváření objektů třídy CMemFile. První konstruktor CMemFile má pouze jeden volitelný parametr nGrowBytes:

    CMemFile(UINT nGrowBytes=1024);

    Tento konstruktor vytvoří prázdný soubor v paměti RAM. Po vytvoření se soubor automaticky otevře (není třeba volat Ope

    n).

    Při zahájení zápisu do takového souboru je automaticky přidělen blok paměti. Chcete-li získat metody paměťové třídy

    CMemFilevolání standardních funkcímalloc, realloc A volný, uvolnit. Pokud je přidělený paměťový blok nedostatečný, jeho velikost se zvětší. Ke zvýšení bloku paměti souboru dochází po částech o nGrowBytes bajtů. Po odstranění objektu třídyCMemFilepoužitá paměť se automaticky vrátí do systému.

    Druhý konstruktor třídy CMemFile má složitější prototyp. Tento konstruktor se používá, když programátor sám alokuje paměť pro soubor:

    CMemFile(BYTE* lpBuffer, UINT nBufferSize, UINT nGrowBytes=0);

    Parametr lpBuffer ukazuje na vyrovnávací paměť, která má být použita pro soubor. Velikost vyrovnávací paměti je určena parametrem nBufferSize.

    Volitelný parametr nGrowBytes se používá složitějším způsobem než v konstruktoru první třídy. Pokud je nGrowBytes nula, pak vygenerovaný soubor bude obsahovat data z lpBuffer. Délka takového souboru bude rovna nBufferSize.

    Pokud je nGrowBytes větší než nula, bude obsah lpBuffer ignorován. Pokud je navíc do takového souboru zapsáno více dat, než se vejde do přidělené vyrovnávací paměti, pak se jeho velikost automaticky zvětší. Ke zvýšení bloku paměti souboru dochází po částech o nGrowBytes bajtů.

    CMemFileumožňuje získat ukazatel na paměťovou oblast používanou souborem. Prostřednictvím tohoto ukazatele můžete přímo pracovat s obsahem souboru, aniž byste se omezovali na metody třídyCFile. K získání ukazatele na vyrovnávací paměť souboru můžete použít metodu Detach. Než to uděláte, je užitečné určit délku souboru (a podle toho i velikost vyrovnávací paměti) voláním metodyGetLength. Odpojitzavře daný soubor a vrátí ukazatel na blok paměti, který používá. Pokud potřebujete soubor znovu otevřít a přidružit k němu blok operační paměti, musíte metodu zavolatPřipojit.

    Je třeba poznamenat, že za účelem správy vyrovnávací paměti souboru, třídy

    CMemFilevolá standardní funkcemalloc, realloc A volný, uvolnit. Proto, aby nedošlo k porušení mechanismu správy paměti, musí být funkcemi vytvořena vyrovnávací paměť lpBuffermalloc nebo calloc.

    Třída CStdioFile

    Ti, kteří jsou zvyklí používat funkce streamu I/O ze standardních knihoven C a C++, by se měli podívat na třídu

    CStdioFile, zděděné ze základní třídyCFile. Tato třída vám umožňuje provádět I/O s vyrovnávací pamětí v textovém a binárním režimu. Pro objekty třídyCStdioFilemůžete volat téměř všechny metody třídy CFile.CStdioFileobsahuje datový prvek m_pStream, který obsahuje ukazatel na otevřený soubor. Pokud je objekt třídyCStdioFilevytvořen, ale soubor ještě nebyl otevřen nebo uzavřen, pak m_pStream obsahuje konstantu NULL.CStdioFilemá tři různé konstruktéry. První konstruktor třídy CStdioFile nemá žádné parametry. Tento konstruktor pouze vytvoří objekt třídy, ale neotevírá žádné soubory. Chcete-li otevřít soubor, musíte zavolat metoduOTEVŘENOzákladní třídaCFile.

    Konstruktor druhé třídy

    CStdioFilelze volat, pokud je soubor již otevřený a potřebujete vytvořit nový objekt třídy CStdioFile a přidružit k němu otevřený soubor. Tento konstruktor lze použít, pokud byl soubor otevřen standardní funkcífopen. Parametr metody musí obsahovat ukazatel na soubor získaný voláním standardní funkcefopen.

    Třetí konstruktor lze použít, pokud potřebujete vytvořit objekt třídy

    CStdioFile, otevřete nový soubor a propojte jej s nově vytvořeným objektem.

    Pro čtení a zápis do textového souboru obsahuje třída CStdioFile dvě nové metody:

    ReadString A WriteString. První metoda umožňuje číst řetězec znaků ze souboru a druhá metoda umožňuje jeho zápis.

    Příklady zápisu a čtení ze souboru

    Zde jsou úryvky kódu, které demonstrují použití standardních dialogových oken pro výběr souboru a postup pro čtení a zápis do souboru.

    Otevření souboru a čtení z něj

    CString m_Text; …… // vytvoření standardního panelu pro výběr souboru Otevřít CFileDialog DlgOpen(TRUE,(LPCSTR)"txt",NULL, OFN_HIDEREADONLY,(LPCSTR)" Textové soubory (*.txt) |*.txt||"); // zobrazení standardního panelu pro výběr souboru Otevřít if(DlgOpen.DoModal()==IDOK) ( // vytvořte objekt a otevřete soubor pro čtení Soubor CStdioFile(DlgOpen.GetPathName(),CFile::modeRead|CFile::typeBinary); // přečtení řádku ze souboru CString& ref=m_Text; File.ReadString(ref ); // je předán odkaz na řetězec m_Text )

    Otevření souboru a zápis z něj

    CString m_Text; …… // vytvoří standardní panel pro výběr souboru SaveAs CFileDialog DlgSaveAs(FALSE,(LPCSTR)"txt",NULL, OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, (LPCSTR)" Textové soubory (*.txt) |*.txt||"); // zobrazení standardního panelu pro výběr souboru SaveAs if(DlgSaveAs.DoModal()==IDOK) ( // vytvořte objekt a otevřete soubor pro zápis Soubor CStdioFile(DlgSaveAs.GetPathName(), CFile::modeCreate|CFile::modeWrite|CFile::typeBinary); // zápis řetězce do souboru File.WriteString((LPCTSTR)m_Text); )
      je pracovní kód programu vytvořený pro jednoduchost ve formě konzolové aplikace pod MFC. Aby program fungoval, nezapomeňte udělat následující:

      Spusťte program - Build / Rebuild all (budou se vyskytovat chyby), vyberte Build / Set aktivní konfigurace - Win 32 Realise, vyberte položku nabídky "Project", poté "Settings ...", "C / C ++" záložka Kategorie - Generování kódu a pod "Použít knihovnu za běhu" vyberte "Vícevláknové". Poté proveďte Build / Rebuild all znovu a program bude fungovat.

    Poslední aktualizace: 31.10.2015

    Třída filestream představuje schopnost číst ze souboru a zapisovat do souboru. Umožňuje pracovat s textovými i binárními soubory.

    Zvažte jeho nejdůležitější vlastnosti a metody:

      Vlastnost Length: vrací délku proudu v bajtech

      Vlastnost Position: vrací aktuální pozici ve streamu

      Metoda čtení: Čte data ze souboru do bajtového pole. Vyžaduje tři parametry: int Read(bajtové pole, int offset, int počet) a vrátí počet úspěšně přečtených bajtů. Používají se zde následující parametry:

      • pole - pole bajtů, kam budou umístěna data načtená ze souboru

        offset představuje posun v bajtech v poli, do kterého budou umístěny přečtené bajty

        počet – maximální počet bajtů, které mají být načteny. Pokud je v souboru méně bajtů, přečtou se všechny.

      Metoda dlouhé hledání (dlouhý posun, původ SeekOrigin): nastavuje pozici v toku offsetu o počet bajtů zadaný v parametru offset.

      Metoda zápisu: Zapíše data z pole bajtů do souboru. Vyžaduje tři parametry: Write (bajtové pole, int offset, int count)

      • pole - pole bajtů, odkud budou data zapsána do souboru

        offset - offset v bajtech v poli pole, odkud začít zapisovat bajty do proudu

        počet – maximální počet zapsaných bajtů

    FileStream představuje přístup k souborům na úrovni bajtů, takže pokud například potřebujete číst nebo zapisovat jeden nebo více řádků do textového souboru, pak je třeba pole bajtů převést na řetězce pomocí speciálních metod. Pro práci s textovými soubory se proto používají jiné třídy.

    Zároveň při práci s různými binárními soubory, které mají určitou strukturu, může být FileStream velmi užitečný pro extrakci určitých informací a jejich zpracování.

    Podívejme se na příklad čtení a zápisu do textového souboru:

    Console.WriteLine("Zadejte řádek pro zápis do souboru:"); string text = Console.ReadLine(); // zápis do souboru pomocí (FileStream fstream = new FileStream(@"C:\SomeDir\noname\note.txt", FileMode.OpenOrCreate)) ( // převod řetězce na pole bajtů bajtů = System.Text.Encoding.Default. GetBytes(text); // Zápis pole bajtů do souboru fstream.Write(pole, 0, pole.Length); Console.WriteLine("Text je zapsán do souboru"); ) // Čtení ze souboru pomocí (FileStream fstream = Soubor. OpenRead(@"C:\SomeDir\noname\note.txt")) ( // převod řetězce na pole bajtů bajtů = nový bajt; // čtení dat fstream.Read(pole, 0, pole. Length); // dekódování bajtů na řetězec textFromFile = System.Text.Encoding.Default.GetString(pole); Console.WriteLine("Text ze souboru: (0)", textFromFile); ) Console.ReadLine();

    Pojďme analyzovat tento příklad. Čtení i zápis používají příkaz using. Toto prohlášení by se nemělo zaměňovat s direktivou using, která zahrnuje jmenné prostory na začátku souboru kódu. Příkaz using umožňuje vytvořit objekt v bloku kódu, načež je zavolána metoda Dispose na tomto objektu, a tím je objekt zničen. V tomto případě jako takový objekt slouží proměnná fstream.

    Objekt fstream je vytvořen dvěma různými způsoby: pomocí konstruktoru a pomocí jedné ze statických metod třídy File.

    Zde jsou konstruktoru předány dva parametry: cesta k souboru a výčet FileMode. Tento výčet označuje režim přístupu k souboru a může nabývat následujících hodnot:

      Append : Pokud soubor existuje, pak se text připojí na konec souboru. Pokud soubor neexistuje, je vytvořen. Soubor je otevřen pouze pro zápis.

      Vytvořit: Vytvoří se nový soubor. Pokud takový soubor již existuje, je přepsán

      CreateNew : Vytvoří se nový soubor. Pokud takový soubor již existuje, pak aplikace vyvolá chybu

      Otevřít: Otevře soubor. Pokud soubor neexistuje, je vyvolána výjimka.

      OpenOrCreate : pokud soubor existuje, je otevřen, pokud ne, je vytvořen nový

      Zkrátit: Pokud soubor existuje, bude přepsán. Soubor je otevřen pouze pro zápis.

    Statická metoda OpenRead třídy File otevře soubor pro čtení a vrátí objekt FileStream.

    Konstruktor pro třídu FileStream má také řadu přetížení, která vám umožňují doladit vytvářený objekt. Všechny tyto verze lze zobrazit na msdn.

    Zápis i čtení používají objekt kódování Encoding.Default ze jmenného prostoru System.Text. V tomto případě používáme dvě jeho metody: GetBytes k získání bajtového pole z řetězce a GetString k získání řetězce z bajtového pole.

    Výsledkem je, že řetězec, který jsme zadali, se zapíše do souboru note.txt. Ve skutečnosti se jedná o binární soubor (nikoli textový), i když pokud do něj napíšeme pouze řádek, můžeme si tento soubor zobrazit v lidsky čitelné podobě otevřením v textovém editoru. Pokud do něj ale zapíšeme náhodné bajty, například:

    Fstream.WriteByte(13); fstream.WriteByte(103);

    Pak můžeme mít problém to pochopit. Proto jsou samostatné třídy navrženy pro přímou práci s textovými soubory – StreamReader a StreamWriter.

    Náhodný přístup k souboru

    Není neobvyklé, že binární soubory představují určitou strukturu. A při znalosti této struktury můžeme vzít potřebnou část informací ze souboru nebo naopak zapsat určitou sadu bajtů na určité místo v souboru. Například v souborech wav začínají samotná zvuková data na 44 bajtech a až 44 bajtů jsou různá metadata - počet zvukových kanálů, vzorkovací frekvence atd.

    Pomocí metody Seek() můžeme ovládat pozici kurzoru proudu, ze kterého se soubor čte nebo do kterého se zapisuje. Tato metoda má dva parametry: offset (offset) a pozici v souboru. Pozice v souboru je popsána třemi hodnotami:

      SeekOrigin.Begin : začátek souboru

      SeekOrigin.End : konec souboru

      SeekOrigin.Current : aktuální pozice v souboru

    Kurzor proudu, ze kterého začíná čtení nebo zápis, se posune dopředu o hodnotu offsetu vzhledem k pozici zadané jako druhý parametr. Posun může být záporný, pak se kurzor přesune zpět, pokud je kladný, pak dopředu.

    Podívejme se na příklad:

    Pomocí System.IO; pomocí System.Text; class Program ( static void Main(string args) ( string text = "hello world"; // zápis do souboru pomocí (FileStream fstream = new FileStream(@"D:\note.dat", FileMode.OpenOrCreate)) ( // převést řetězec na bajty byte input = Encoding.Default.GetBytes(text); // zapsat pole bajtů do souboru fstream.Write(input, 0, input.Length); Console.WriteLine("Text zapsaný do souboru"); / / přesunout ukazatel na konec souboru, na konec souboru - pět bajtů fstream.Seek(-5, SeekOrigin.End); // mínus 5 znaků od konce streamu // čtení čtyř znaků z aktuální pozice byte output = nový byte; fstream.Read( output, 0, output.Length); // dekódování bajtů do řetězce textFromFile = Encoding.Default.GetString(output); Console.WriteLine("Text ze souboru: (0)", textFromFile); // worl // nahrazení v souboru word world na word house řetězec nahraditText = "house"; fstream.Seek(-5, SeekOrigin.End); // minus 5 znaků od konce vstup proudu = Encoding.Default.GetBytes(replaceText);fstream.Write(input , 0, input.Length); // přečte celý soubor // vrátí ukazatel na začátek souboru fstream.Seek(0, SeekOrigin.Begin); výstup = nový byte; fstream.Read(výstup, 0, výstup.Délka); // dekódování bajtů na řetězec textFromFile = Encoding.Default.GetString(output); Console.WriteLine("Text ze souboru: (0)", textFromFile); // ahoj dome ) Console.Read(); ))

    Výstup konzole:

    Text zapsaný do souboru Text ze souboru: worl Text ze souboru: hello house

    Volání fstream.Seek(-5, SeekOrigin.End) přesune kurzor streamu na konec souborů o pět znaků zpět:

    To znamená, že po zapsání řetězce "hello world" do nového souboru bude kurzor na pozici znaku "w".

    Poté přečteme čtyři bajty začínající znakem "w". V tomto kódování bude 1 znak představovat 1 bajt. Proto čtení 4 bajtů bude ekvivalentní čtení čtyř znaků: "svět".

    Poté se opět přesuneme na konec souboru, nedosáhneme konce pěti znaků (tedy opět z pozice znaku "w") a napíšeme řádek "dům". Řetězec "dům" tedy nahrazuje řetězec "svět".

    Uzavření streamu

    Výše uvedené příklady používají konstrukci using k uzavření proudu. Po dokončení všech příkazů a výrazů v bloku using je objekt FileStream zničen. Můžeme však zvolit jiný způsob:

    FileStream fstream = null; zkuste ( fstream = new FileStream(@"D:\note3.dat", FileMode.OpenOrCreate); // operace streamování ) catch(Exception ex) ( ) nakonec ( if (fstream != null) fstream.Close(); )

    Pokud nepoužijeme konstrukci using, pak musíme explicitně zavolat metodu Close(): fstream.Close()

    Většina počítačových programů pracuje se soubory, a proto je potřeba soubory vytvářet, mazat, zapisovat, číst, otevírat. Co je to soubor? Soubor je pojmenovaná kolekce bajtů, která může být uložena na nějakém úložném zařízení. No, teď je jasné, že soubor je nějaká posloupnost bajtů, která má svůj vlastní jedinečný název, například soubor .txt. Soubory se stejným názvem nemohou být ve stejném adresáři. Název souboru je chápán nejen jako jeho název, ale také jako přípona, například: soubor.txt a soubor.dat různé soubory, i když mají stejný název. Existuje něco jako úplný název souborů - jedná se o úplnou adresu do adresáře souboru s názvem souboru, například: D:\docs\file.txt . Je důležité porozumět těmto základním pojmům, jinak bude obtížné pracovat se soubory.

    Chcete-li pracovat se soubory, musíte zahrnout soubor záhlaví . V několik definovaných tříd a hlavičkových souborů vstup do souboru a výstup souboru.

    File I/O je podobný standardnímu I/O, jediný rozdíl je v tom, že I/O se neprovádí na obrazovku, ale do souboru. Pokud je vstup/výstup na standardní zařízení prováděn pomocí objektů cin a cout, pak pro organizaci souborových I/O stačí vytvořit vlastní objekty, které lze použít podobně jako operátory cin a cout.

    Například je potřeba vytvořit textový soubor a do něj napsat řádek Práce se soubory v C++. Chcete-li to provést, musíte provést následující kroky:

    1. vytvořit objekt třídy proudu ;
    2. asociovat objekt třídy se souborem, do kterého se má zapisovat;
    3. napsat řádek do souboru;
    4. zavřete soubor.

    Proč je nutné vytvořit objekt třídy ofstream a ne třídy ifstream? Protože potřebujete zapisovat do souboru a pokud byste potřebovali číst data ze souboru, pak by se vytvořil objekt třídy ifstream.

    // vytvořte objekt pro zápis do souboru ofstream /*jméno objektu*/; // objekt třídy proudu

    Nazvěme objekt - fout , Zde je to, co se stane:

    Ofstream fout;

    Proč potřebujeme předmět? Objekt musí být schopen zapisovat do souboru. Objekt již byl vytvořen, ale není přidružen k souboru, do kterého má být řetězec zapsán.

    fout.open("cppstudio.txt"); // asociovat objekt se souborem

    Prostřednictvím operace tečka získáme přístup k metodě třídy open(), v jejíž závorce uvedeme název souboru. Zadaný soubor bude vytvořen v aktuálním adresáři s programem. Pokud existuje soubor se stejným názvem, stávající soubor bude nahrazen novým. Soubor je tedy otevřený, zbývá do něj napsat požadovaný řádek. Dělá se to takto:

    Fout<< "Работа с файлами в С++"; // запись строки в файл

    Pomocí operace cast to stream ve spojení s objektem fout je řetězec File Handling v C++ zapsán do souboru. Protože již není nutné měnit obsah souboru, musí být uzavřen, to znamená, že objekt by měl být oddělen od souboru.

    fout.close(); // zavřete soubor

    V důsledku toho byl vytvořen soubor s řádkem Práce se soubory v C++.

    Kroky 1 a 2 lze kombinovat, to znamená v jednom řádku vytvořit objekt a přiřadit jej k souboru. Dělá se to takto:

    Ofstream fout("cppstudio.txt"); // vytvoří objekt třídy ofstream a přiřadí jej k souboru cppstudio.txt

    Zkombinujme celý kód a získáme následující program.

    // soubor.cpp: definuje vstupní bod pro konzolovou aplikaci. #include "stdafx.h" #include pomocí jmenného prostoru std; int main(int argc, char* argv) ( ofstream fout("cppstudio.txt"); // vytvořte objekt třídy ofstream pro zápis a přidružte jej k souboru cppstudio.txt fout<< "Работа с файлами в С++"; // запись строки в файл fout.close(); // закрываем файл system("pause"); return 0; }

    Zbývá zkontrolovat správnou činnost programu, a proto soubor otevřeme cppstudio.txt a podívejte se na jeho obsah, mělo by to být - Práce se soubory v C++.

    1. vytvořit objekt třídy ifstream a přiřadit jej k souboru, ze kterého se má číst;
    2. číst soubor;
    3. zavřete soubor.
    // file_read.cpp: definuje vstupní bod pro konzolovou aplikaci. #include "stdafx.h" #include #zahrnout pomocí jmenného prostoru std; int main(int argc, char* argv) ( setlocale(LC_ALL, "rus"); // správné zobrazení char buff v azbuce; ​​// mezipaměť pro ukládání textu načteného ze souboru ifstream fin("cppstudio.txt "); // otevření souboru pro čtení fin >><< buff << endl; // напечатали это слово fin.getline(buff, 50); // считали строку из файла fin.close(); // закрываем файл cout << buff << endl; // напечатали эту строку system("pause"); return 0; }

    Program ukazuje dva způsoby čtení ze souboru, prvním je použití operace přenosu do streamu, druhým je použití funkce getline() . V prvním případě se přečte pouze první slovo a ve druhém případě se přečte řetězec 50 znaků. Ale protože v souboru zbývá méně než 50 znaků, znaky se přečtou až do posledního včetně. Všimněte si, že čtení podruhé (řádek 17) pokračoval po prvním slově, a ne od začátku, protože první slovo bylo přečtenořádek 14. Výsledek programu je na obrázku 1.

    Práce se soubory v C++ Pokračujte stisknutím libovolné klávesy. . .

    Obrázek 1 - Práce se soubory v C++

    Program fungoval správně, ale není tomu tak vždy, i když je vše v pořádku s kódem. Programu byl například předán název neexistujícího souboru nebo došlo k chybě v názvu. Co pak? V tomto případě se nestane vůbec nic. Soubor nebude nalezen, což znamená, že jej nelze přečíst. Proto bude kompilátor ignorovat řádky, kde je soubor zpracováván. V důsledku toho se program správně ukončí, ale na obrazovce se nic nezobrazí. Zdálo by se, že jde o zcela normální reakci na takovou situaci. Prostý uživatel však nepochopí, o co jde a proč se na obrazovce neobjevil řádek ze souboru. Aby bylo vše velmi jasné, C++ poskytuje takovou funkci - is_open() , která vrací celočíselné hodnoty: 1 - pokud byl soubor úspěšně otevřen, 0 - pokud soubor nebyl otevřen. Dokončíme program otevřením souboru tak, že pokud se soubor neotevře, zobrazí se odpovídající zpráva.

    // file_read.cpp: definuje vstupní bod pro konzolovou aplikaci. #include "stdafx.h" #include #zahrnout pomocí jmenného prostoru std; int main(int argc, char* argv) ( setlocale(LC_ALL, "rus"); // správné zobrazení cyrilického znakového buffu; // přechodná vyrovnávací paměť pro text načtený ze souboru ifstream fin("cppstudio.doc"); / / ( ZADAL NESPRÁVNÝ NÁZEV SOUBORU) if (!fin.is_open()) // pokud soubor není otevřený cout<< "Файл не может быть открыт!\n"; // сообщить об этом else { fin >> buff; // přečtení prvního slova ze souboru cout<< buff << endl; // напечатали это слово fin.getline(buff, 50); // считали строку из файла fin.close(); // закрываем файл cout << buff << endl; // напечатали эту строку } system("pause"); return 0; }

    Výsledek programu je na obrázku 2.

    Soubor nelze otevřít! Pokračujte stiskem libovolné klávesy. . .

    Obrázek 2 - Práce se soubory v C++

    Jak můžete vidět na obrázku 2, program hlásil, že soubor nelze otevřít. Pokud tedy program pracuje se soubory, doporučuje se použít tuto funkci is_open() , i když jste si jisti, že soubor existuje.

    Režimy otevírání souborů

    Režimy otevírání souborů určují způsob použití souborů. Pro nastavení režimu poskytuje třída ios_base konstanty, které určují režim otevírání souboru (viz Tabulka 1).

    Režimy otevírání souborů lze nastavit přímo při vytváření objektu nebo při volání funkce open(). .

    Ofstream fout("cppstudio.txt", ios_base::app); // otevření souboru pro přidání informací na konec souboru fout. open("cppstudio.txt", ios_base::app); // otevřete soubor pro přidání informací na konec souboru

    Režimy otevření souboru lze kombinovat pomocí bitové booleovské operace nebo| , například: ios_base::out | ios_base::trunc - otevřete soubor pro zápis po jeho vymazání.

    Objekty třídy ofstream , jsou-li spojeny se soubory, standardně obsahují režimy otevírání souborů ios_base::out | ios_base::trunc . To znamená, že soubor bude vytvořen, pokud neexistuje. Pokud soubor existuje, jeho obsah bude smazán a samotný soubor bude připraven k nahrávání. Objekty třídy ifstream, jsou-li spojeny se souborem, mají ve výchozím nastavení režim otevírání souboru ios_base::in - soubor je otevřen pouze pro čtení. Režimu otevírání souborů se také říká příznak, kvůli čitelnosti budeme tento termín v budoucnu používat. Tabulka 1 neuvádí všechny příznaky, ale pro začátek by vám měly stačit.

    Vezměte prosím na vědomí, že příznaky ate a app jsou velmi podobné v popisu, oba přesouvají ukazatel na konec souboru, ale příznak aplikace umožňuje zápis pouze na konec souboru a příznak ate jednoduše přeuspořádá příznak na konec souboru a neomezuje prostor pro nahrávání.

    Pojďme vyvinout program, který pomocí operace sizeof() vypočítá charakteristiky hlavních datových typů v C++ a zapíše je do souboru. Vlastnosti:

    1. počet bajtů přidělených pro datový typ
    2. maximální hodnota, kterou může konkrétní datový typ uložit.

    Zápis do souboru musí být v následujícím formátu:

    /* datový typ byte max. hodnota bool = 1 255,00 char = 1 255,00 short int = 2 32767,00 unsigned short int = 2 65535,00 int = 4 2147483647,00 unsigned int = 4 670629,00 unsigned int = 4 670629,00 7,00 unsigned long int = 4 4294967295,00 float = 4 2147483647,00 dlouhý plovák = 8 9223372036854775800,00 dvojitý = 8 9223372036854775800,00 */

    Takový program již byl vyvinut dříve v této části, ale tam byly všechny informace o datových typech vyvedeny na standardní výstupní zařízení a my musíme program předělat tak, aby se informace zapisovaly do souboru. Chcete-li to provést, musíte soubor otevřít v režimu zápisu s předběžným zkrácením informací o aktuálním souboru ( řádek 14). Jakmile je soubor vytvořen a úspěšně otevřen (řádky 16 - 20), místo příkazu cout v řádek 22 použijte objekt fout. tedy místo obrazovky budou informace o datových typech zapsány do souboru.

    // write_file.cpp: definuje vstupní bod pro konzolovou aplikaci. #include "stdafx.h" #include #zahrnout // práce se soubory #include // I/O manipulátory používající jmenný prostor std; int main(int argc, char* argv) ( setlocale(LC_ALL, "rus"); // propojí objekt se souborem, přičemž soubor otevírá v režimu zápisu a nejprve z něj odstraní všechna data ze streamu fout("data_types.txt ", ios_base::out | ios_base::trunc); if (!fout.is_open()) // pokud soubor nebyl otevřen ( cout<< "Файл не может быть открыт или создан\n"; // напечатать соответствующее сообщение return 1; // выполнить выход из программы } fout << " data type " << "byte" << " " << " max value "<< endl // záhlaví sloupců <<"bool = " << sizeof(bool) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных bool*/ << (pow(2,sizeof(bool) * 8.0) - 1) << endl << "char = " << sizeof(char) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных char*/ << (pow(2,sizeof(char) * 8.0) - 1) << endl << "short int = " << sizeof(short int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных short int*/ << (pow(2,sizeof(short int) * 8.0 - 1) - 1) << endl << "unsigned short int = " << sizeof(unsigned short int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных unsigned short int*/ << (pow(2,sizeof(unsigned short int) * 8.0) - 1) << endl << "int = " << sizeof(int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных int*/ << (pow(2,sizeof(int) * 8.0 - 1) - 1) << endl << "unsigned int = " << sizeof(unsigned int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных unsigned int*/ << (pow(2,sizeof(unsigned int) * 8.0) - 1) << endl << "long int = " << sizeof(long int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных long int*/ << (pow(2,sizeof(long int) * 8.0 - 1) - 1) << endl << "unsigned long int = " << sizeof(unsigned long int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных undigned long int*/ << (pow(2,sizeof(unsigned long int) * 8.0) - 1) << endl << "float = " << sizeof(float) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных float*/ << (pow(2,sizeof(float) * 8.0 - 1) - 1) << endl << "long float = " << sizeof(long float) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных long float*/ << (pow(2,sizeof(long float) * 8.0 - 1) - 1) << endl << "double = " << sizeof(double) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных double*/ << (pow(2,sizeof(double) * 8.0 - 1) - 1) << endl; fout.close(); // программа больше не использует файл, поэтому его нужно закрыть cout << "Данные успешно записаны в файл data_types.txt\n"; system("pause"); return 0; }

    Není možné si nevšimnout, že změny v programu jsou minimální a to vše díky tomu, že standardní vstup/výstup a souborový vstup/výstup jsou využívány naprosto stejně. Na konci programuřádek 45soubor jsme výslovně uzavřeli, ačkoli to není vyžadováno, považuje se to za dobrou programátorskou praxi. Stojí za zmínku, že všechny funkce a manipulátory používané pro formátování standardního vstupu/výstupu jsou relevantní i pro vstup/výstup souboru. Při obsluze tedy nedošlo k žádným chybám cout byl nahrazen předmětem fout.

    Mechanismus I/O vyvinutý společností , neodpovídá dnes obecně přijímanému stylu objektově orientovaného programování, navíc aktivně využívá ukazatelové operace, které jsou v moderních prostředích spouštění zabezpečeného kódu považovány za potenciálně nebezpečné. Alternativou pro vývoj aplikací je standardní mechanismus I/O tříd poskytovaný standardem jazyka C++.

    Otevírání souborů

    Nejčastěji používané třídy jsou ifstream pro čtení, ofstream pro zápis a fstream pro úpravu souborů.

    Všechny třídy I/O s vlákny jsou nepřímo odvozeny od společného předka ios a plně zdědí jeho funkčnost. Například výčtový datový člen open_mode určuje režim otevření souboru, který je definován následovně:

    Enum open_mode ( app, binary, in, out, trunc, ate );

    Níže jsou uvedeny možné hodnoty příznaků a jejich účel.

    Chcete-li například otevřít soubor s názvem test.txt pro čtení binárních dat, napište:

    ifstream soubor; file.open("test.txt", ios::in | ios::binary);

    Logický operátor OR (|) vám umožňuje sestavit režim s libovolnou kombinací příznaků. Abyste při otevírání souboru zápisem omylem nepřepsali existující soubor se stejným názvem, musíte použít následující formulář:

    offstream soubor; file.open("test.txt", ios::out | ios::app);

    Předpokládá se, že k projektu je připojen příslušný hlavičkový soubor:

    #zahrnout

    Chcete-li zkontrolovat, zda byl soubor úspěšně otevřen, můžete použít konstrukci

    If (!file) ( // Zpracování chyby při otevření souboru )

    Operátoři inkluze a těžby

    Přepsáno ve třídách zpracování souborů zahrnout operátora (<<) записывает данные в файловый поток. Как только вы открыли файл для записи, можно записывать в него текстовую строку целиком:

    Soubor<< "Это строка текста";

    Textový řetězec můžete také napsat po částech:

    Soubor<< "Это " << "строка " << "текста";

    Příkaz endl ukončí vstup řádku návratem vozíku:

    Soubor<< "Это строка текста" << endl;

    Pomocí operátoru include je snadné zapsat hodnoty proměnných nebo prvků pole do souboru:

    Ofstream soubor("Temp.txt"); char buff = "Textové pole obsahuje proměnné"; int vx = 100; plovák pi = 3,14159; soubor<< buff << endl << vx << endl << pi << endl;

    V důsledku spuštění kódu se vygenerují tři řádky textového souboru Temp.txt:

    Textové pole obsahuje proměnné 100 3,14159

    Všimněte si, že číselné hodnoty se do souboru zapisují jako textové řetězce, nikoli binární hodnoty.

    operátor extraktu(>>) dělá opak. Zdá se, že k extrahování znaků ze souboru Temp.txt napsaného dříve, musíte napsat kód jako následující:

    ifstream soubor("Temp.txt"); char buff; intvx; floatpi; soubor >> buff >> vx >> pi;

    Operátor extrakce se však zastaví u prvního oddělovače (mezera, tabulátor nebo nový řádek), na který narazí. Při analýze věty „Textové pole obsahuje proměnné“ se tedy do pole buff zapíše pouze slovo „Text“, mezera se ignoruje a slovo „pole“ se stane hodnotou celočíselné proměnné vx a kódu provedení se „zničí“ s nevyhnutelným porušením datové struktury. Dále si při probírání třídy ifstream ukážeme, jak správně organizovat čtení souboru z předchozího příkladu.

    ifstream třída: čtení souborů

    Jak název napovídá, třída ifstream je navržena pro vstup datového proudu souboru. Hlavní metody třídy jsou uvedeny níže. Většina z nich je zděděna z třídy istream a přetížena rodičovskou funkcí. Například funkce get je v závislosti na parametru volání schopna číst nejen jeden znak, ale i blok znaků.

    Nyní je jasné, jak je třeba upravit předchozí příklad, aby použití operátoru extrakce dat poskytlo očekávaný výsledek:

    ifstream soubor("Temp.txt"); char buff; intvx; floatpi; file.getline(buff, sizeof(buff)); soubor >> vx >> pi:

    Metoda getline přečte první řádek souboru až do konce a operátor >> přiřadí hodnoty proměnným.

    Následující příklad ukazuje přidání dat do textového souboru a následné čtení celého souboru. Smyčka while (1) se používá místo while(!file2.eof()) z důvodů uvedených v .

    #zahrnout #zahrnout pomocí jmenného prostoru std; int main() ( soubor ofstream; file.open("test.txt",ios::out|ios::app); if (!soubor) ( cout<< "File error - can"t open to write data!"; cin.sync(); cin.get(); return 1; } for (int i=0; i<10; i++) file << i << endl; file.close(); ifstream file2; file2.open("test.txt", ios::in); if (!file2) { cout << "File error - can"t open to read data!"; cin.sync(); cin.get(); return 2; } int a,k=0; while (1) { file2 >>a; if (file2.eof()) break; cout<< a << " "; k++; } cout << endl << "K=" << k << endl; file2.close(); cin.sync(); cin.get(); return 0; }

    Následující příklad prochází čtením řádků ze souboru test.txt a jejich zobrazením na konzole.

    #zahrnout #zahrnout pomocí jmenného prostoru std; int main() ( soubor ifstream; // vytvoření souboru objektu streamu file.open("test.txt"); // otevření souboru pro čtení if (!soubor) návrat 1; // návrat při chybě otevření char str; / / static line buffer // Čtení a zobrazování řádků ve smyčce až do eof while (!file.getline(str, sizeof(str)).eof()) cout<< str << endl; // вывод прочитанной строки на экран cin.sync(); cin.get(); return 0; }

    Tento kód pod OS Windows také závisí na přítomnosti znaku nového řádku v posledním řádku souboru, bylo by spolehlivější to udělat:

    While (1) ( if (file.eof()) break; file.getline(str, sizeof(str)); cout<< str << endl; }

    Explicitní volání metod open a close jsou volitelné. Volání konstruktoru s argumentem vám skutečně umožní otevřít soubor okamžitě, v okamžiku vytvoření objektu streamu souboru:

    ifstream soubor("test.txt");

    Místo metody close můžete použít operátor delete, který automaticky zavolá destruktor objektu souboru a zavře soubor. Kód smyčky while poskytuje správnou kontrolu konce souboru.

    ofstream class: zápis souborů

    Třída ofstream je navržena pro výstup dat z datového proudu souborů. Hlavní metody této třídy jsou uvedeny níže.

    Operátor include popsaný výše je vhodný pro organizaci zápisu do textového souboru:

    Ofstream soubor("temp.txt"); if (!soubor) return; pro (int i=1; i<=3; i++) file << "Строка " << i << endl; file.close();

    Binární soubory

    V zásadě se binární data obsluhují jako textová data. Rozdíl je v tom, že pokud jsou binární data zapsána v určité logické struktuře, musí být načtena ze souboru do proměnné stejného typu struktury.

    První parametr metod zápisu a čtení (adresa bloku zápisu/čtení) musí být typu znakového ukazatele char * , je tedy nutné explicitně převést typ adresy struktury void *. Druhý parametr určuje, že binární bloky souboru mají konstantní velikost bajtů bez ohledu na skutečnou délku záznamu. Následující příloha uvádí příklad, jak vytvořit a zobrazit data v jednoduchém poznámkovém bloku. Záznamy souboru jsou pak postupně čteny a zobrazeny na konzole.

    #zahrnout #zahrnout #zahrnout pomocí jmenného prostoru std; struct Poznámky ( // datová struktura zápisníku char Name; // celé jméno char Phone; // phone int Age; // age ); int main() ( setlocale(LC_ALL, "Russian"); Notes Note1= ("Grozny Ioann Vasilyevich", "nenainstalováno", 60 ); Notes Note2= ("Godunov Boris Fedorovich", "095-111-2233 ", 30 ); Notes Note3= ( "Peter Romanov ", "812-333-2211", 20 ); ofstream ofile("Notebook.dat", ios::binary); ofile.write((char*)&Note1, sizeof ( Notes)); // 1. blok souboru.write((znak*)&Poznámka2, velikost(Poznámky)); // 2. blok souboru.write((znak*)&Poznámka3, velikost(Poznámky)); / / 3. blok souboru. close(); // zavře zapsaný soubor ifstream ifile("Notebook.dat", ios::binary); Notes Note; // strukturovaná proměnná char str; // vyrovnávací paměť statického řetězce // Čtení a zobrazování řádků ve smyčce, dokud eof while (!file.read((char*)&Note, sizeof(Notes)).eof()) ( sprintf(str, "%s\tBody: %s\tAge: %d" , Note.Name, Note. Telefon, Poznámka.Věk); cout<< str << endl; } ifile.close(); // закрыть прочитанный файл cin.sync(); cin.get(); return 0; }

    V důsledku provedení tohoto kódu se vytvoří binární soubor Notebook.dat ze tří bloků po 80 bajtech (za předpokladu, že znaky jsou jednobajtové). Samozřejmě můžete použít jiné metody streamování a provádět libovolné operace na polích konkrétní datové struktury.

    třída fstream: náhodný přístup k souboru

    Předpokládejme, že náš zápisník nashromáždil 100 záznamů a my chceme počítat 50. Samozřejmě můžete uspořádat smyčku a přečíst všechny záznamy od prvního po daný. Je zřejmé, že cílenějším řešením je nastavit ukazatel polohy souboru pos přímo na položku 50 a přečíst ji:

    ifstream ifile("Notebook.dat", ios::binary); int pos = 49 * sizeof(Notes); ifile hledat (pos); // hledání 50. položky Poznámky Poznámka; //Poznámky - struktura "záznam" popsaná výše ifile.read((char*)&Note, sizeof(Notes));

    Takové vyhledávací operace jsou účinné, pokud soubor obsahuje záznamy o známé a konstantní velikosti. Chcete-li nahradit obsah libovolné položky, musíte otevřít výstupní proud v režimu úprav:

    Ofstream ofile("Notebook.dat", ios::binary | ios::ate); int pos = 49 * sizeof(Notes); ofile seekp(pos); // hledání 50. noty Notes Note50 = ("Jelcin Boris Nikolajevič", "095-222-3322", 64); ofile.write((char*)&Poznámka, velikost(Poznámky)); // výměna, nahrazení

    Pokud nezadáte příznak ios::ate (nebo ios::app), pak při otevření binárního souboru Notebook.dat bude jeho předchozí obsah vymazán!

    Konečně je možné otevřít soubor současně pro čtení/zápis pomocí metod zděděných streamovací třídou fstream od svých předchůdců. Vzhledem k tomu, že třída fstream je odvozena od istream a ostream (rodiče ifstream a ofstream), jsou pro aplikaci dostupné všechny výše uvedené metody.

    Následující příklad zamění první a třetí položku v souboru Notebook.dat.

    #zahrnout #zahrnout #zahrnout pomocí jmenného prostoru std; struct Poznámky ( char Jméno; char Telefon; int Věk; ); int main() ( setlocale(LC_ALL, "Russian"); Notes Note1, Note3; // Otevření souboru pro současné čtení/zápis fstream file("Notebook.dat", ios::binary | ios::in | ios:: out); file.seekg(2 * sizeof(Notes)); // najít a přečíst Note3 file.read((char*)&Note3, sizeof(Notes)); file.seekg(0); // najít a přečíst Note1 file.read((char*)&Note1, sizeof(Notes)); file.seekg(0); // Poznámka1<== Note3 file.write((char*)&Note3, sizeof(Notes)); file.seekg(2 * sizeof(Notes)); // Note3 <== Note1 file.write((char*)&Note1, sizeof(Notes)); char str; // Считывать и отображать записи в цикле, пока не eof file.seekg(0); // вернуться к началу файла while (!file.read((char*)&Note1, sizeof(Notes)).eof()) { sprintf(str, "%s\tТел: %s\tВозраст: %d", Note1.Name, Note1.Phone, Note1.Age); cout << str << endl; } file.close(); cin.sync(); cin.get(); return 0; }

    Příznaky ios::in a ios::out musí být specifikovány v konstruktoru objektu souboru, aby bylo možné provádět souběžné operace čtení a zápisu. V důsledku provedení tohoto kódu dojde k záměně prvního a třetího záznamu binárního souboru Notebook.dat.

    K tématu jsou další příklady.