Kako podesiti pametne telefone i računare. Informativni portal
  • Dom
  • Windows 7, XP
  • Otvaranje fajla. Unos podataka iz datoteke i izlaz u datoteku

Otvaranje fajla. Unos podataka iz datoteke i izlaz u datoteku

Rad sa tekstualnim fajlovima u C++.

Postoje dvije glavne vrste datoteka: tekstualni i binarni. Datoteke omogućavaju korisniku da čita velike količine podataka direktno sa diska bez da ih ukuca sa tastature.

    Tekst nazivaju se datoteke koje se sastoje od bilo kojeg karaktera. Oni su organizirani u redove, od kojih se svaki završava znakom na kraju reda. Kraj samog fajla je označen simbolom "kraj datoteke". Prilikom pisanja informacija u tekstualnu datoteku, koja se može vidjeti pomoću bilo kojeg uređivača teksta, svi podaci se pretvaraju u tip znakova i pohranjuju u obliku znakova.

    AT binarni U datotekama se informacije čitaju i zapisuju u obliku blokova određene veličine, u koje se mogu pohraniti podaci bilo koje vrste i strukture.

Za rad sa fajlovima, specijal tipovi podataka, zvao potoci. Flow ifstream koristi se za rad sa datotekama u načinu čitanja, i van struje u režimu snimanja. Stream se koristi za rad sa datotekama u načinu pisanja i čitanja. fstream.

U C++ programima, kada radite sa tekstualnim datotekama, potrebno je uključiti iostream i fstream biblioteke.

To zapiši podatke u tekstualnu datoteku, morate:

    opisati varijablu tipa toka.

    izlazne informacije u datoteku.

    obavezno zatvorite fajl.

Za čitanja podatke iz tekstualne datoteke, morate:

    opisati varijablu tipa ifstream.

    otvorite datoteku koristeći funkciju otvaranja.

    zatvorite fajl.

Snimanje informacije u tekstualnu datoteku

    Kao što je ranije spomenuto, da biste počeli raditi s tekstualnom datotekom, morate deklarirati varijablu tipa ofstream. Na primjer, ovako:

    Varijabla F će biti kreirana za upisivanje informacija u datoteku.

    Sljedeći korak je otvaranje datoteke za pisanje. Općenito, operator otvaranja toka će izgledati ovako:

F. open("file", mod);

Ovdje je F varijabla deklarirana kao offstream,

file - puno ime datoteke na disku,

mode - način rada sa otvorenim fajlom.

Imajte na umu da kada navodite puno ime datoteke, morate staviti dvostruku kosu crtu. Na primjer, puno ime datoteke noobs.txt koja se nalazi u mapi igre na D: pogonu morat će biti napisano ovako:

D:\\game\\noobs.txt.

Datoteka se može otvoriti na jedan od sljedećih načina:

ios::in - otvori datoteku u načinu čitanja podataka, ovaj način je zadani način za ifstream streamove;

ios::out - otvori datoteku u režimu pisanja podataka (u ovom slučaju, informacije o postojećoj datoteci su uništene), ovaj režim je podrazumevani režim za streamove;

ios::app - otvorite datoteku u načinu upisivanja podataka do kraja datoteke;

ios::ate - prelazak na kraj već otvorenog fajla;

ios::trunc - obrišite datoteku, isto se dešava u ios::out modu;

ios::nocreate - ne otvaraj datoteku ako ne postoji;

ios::noreplace - Ne otvaraj postojeći fajl.

Parametar moda može biti odsutan, u kom slučaju se datoteka otvara u zadanom načinu za ovaj stream.

Nakon uspješnog otvaranja datoteke (u bilo kojem načinu), F varijabla će pohraniti true, a u suprotnom false. Ovo će provjeriti ispravnost operacije otvaranja datoteke.

Možete otvoriti datoteku (uzmimo D:\\game\\noobs.txt kao primjer) u načinu pisanja koristeći jedan od sljedećih metoda:

// prvi način

offstream F;

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

//drugi način, ios::out mod je zadani način

// za protokvan struje

offstream F;

//treći način kombinuje opis varijable i tip toka

//i otvorimo datoteku u jednoj izjavi

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

Nakon otvaranja datoteke u načinu pisanja, kreirat će se prazna datoteka u koju se mogu upisati informacije.

Ako želite da otvorite postojeću datoteku u režimu pre pisanja, koristite ios::app kao režim.

Nakon otvaranja datoteke u načinu pisanja, možete u nju pisati na isti način kao na ekranu, samo umjesto standardnog izlaznog uređajacoutmorate navesti ime otvorene datoteke.

Na primjer, za pisanje varijable a u tok F, izlazni izraz bi bio:

Za sekvencijalno ispis varijabli b, c, d u tok G, izlazni izraz postaje:

G<

Tok se zatvara pomoću operatora:

PRIMJER:

Kreirajte tekstualni fajl D:\\game\\noobs.txt i u njega upišite n realnih brojeva.

#include "stdafx.h"

#include

#include

#include

korištenje imenskog prostora std;

int main()

setlocale(LC_ALL, "RUS");

int i, n;

duplo a;

//opisuje tok za pisanje podataka u datoteku

van struje f;

//otvori datoteku u načinu pisanja,

//modeios:: vaninstaliran prema zadanim postavkama

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

//unesite broj realnih brojeva

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

//petlja za unos realnih brojeva

//i zapisivanje u datoteku

za (i=0; i

cout<<"a=";

//unos broja

cin>>a;

f<

//zatvaranje streama

f.close();

system("pauza");

return 0;

_______________________________________________________________

Da biste pročitali informacije iz tekstualnog fajla, potrebno je deklarisati varijablu tipa ifstream. Nakon toga morate otvoriti datoteku za čitanje pomoću operatora otvoren. Ako se varijabla zove F, tada će prve dvije izjave biti sljedeće:

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

Nakon otvaranja datoteke u načinu čitanja, možete čitati informacije iz nje na isti način kao s tastature, samo umjestocinnavedite ime toka iz kojeg će se podaci čitati.

Na primjer, za čitanje iz toka F u varijablu a, input izraz bi izgledao ovako:

Dva broja u uređivaču teksta smatraju se odvojenima ako između njih postoji barem jedan znak: razmak, tabulator, znak na kraju reda. Dobro je ako programer unaprijed zna koliko i koje vrijednosti treba pohraniti u tekstualnu datoteku. Međutim, često je tip vrijednosti pohranjenih u datoteci jednostavno poznat, a njihov broj može varirati. Da biste riješili ovaj problem, potrebno je da čitate vrijednosti iz datoteke jednu po jednu, a prije svakog čitanja provjerite da li je došlo do kraja datoteke. Za to postoji funkcija F. eof().

Ovdje je F ime toka, funkcija vraća logičku vrijednost: true ili false, ovisno o tome da li je dostignut kraj datoteke. Stoga se petlja za čitanje sadržaja cijele datoteke može napisati ovako:

//organizirati za čitanje vrijednosti iz datoteke, izvršenje

//petlja će se prekinuti kada dođemo do kraja datoteke,

//u ovom slučaju F.eof() će vratiti true

dok (!F.eof())

PRIMJER:

Realni brojevi se pohranjuju u tekstualnu datoteku D:\\game\\noobs.txt, prikažite ih na ekranu i izračunajte njihov broj.

#include "stdafx.h"

#include

#include

#include

#include

korištenje imenskog prostora std;

int main()

setlocale(LC_ALL, "RUS");

intn=0;

float a;

fstream F;

//otvorimo datoteku u načinu čitanja

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

//ako je datoteka ispravno otvorena, onda

//petlja za čitanje vrijednosti iz datoteke; izvođenje petlje će biti prekinuto,

// kada dođemo do kraja datoteke, u kom slučaju će F.eof() vratiti true.

dok (!F.eof())

//čitanje sljedeće vrijednosti iz toka F u varijablu a

F>>a;

//izlaz vrijednosti varijable a na ekran

cout<

//povećavamo broj pročitanih brojeva

//zatvaranje streama

f.close();

//unos broja pročitanih brojeva na ekranu

cout<<"n="<

//ako je datoteka pogrešno otvorena, onda izlaz

//poruke o nepostojanju takve datoteke

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

system("pauza");

return 0;

C++. Obrada binarnih datoteka

Prilikom pisanja informacija u binarnu datoteku, znakovi i brojevi se zapisuju kao niz bajtova.

To zapiši podatke u binarnu datoteku, potrebno je:

    deklarirajte varijablu datoteke tipa FAIL * koristeći izraz FILE *filename;. Ovdje naziv datoteke je ime varijable gdje će biti pohranjen pokazivač na datoteku.

    zapišite informacije u datoteku koristeći funkciju fwrite

To razmisli z podataka iz binarne datoteke, morate:

    opišite varijablu tipa FILE *

    otvorite datoteku sa fopen funkcijom

    zatvorite datoteku sa funkcijom fclose

Osnovne funkcije potrebne za rad s binarnim datotekama.

Za otkrića datoteka, funkcija fopen je namijenjena.

FILE *fopen(const *filename, const char *mode)

Ovdje filename je string koji pohranjuje puno ime datoteke koja se otvara, mode je niz koji definira način rada sa datotekom; moguće su sljedeće vrijednosti:

"rb" - otvaranje binarne datoteke u načinu čitanja;

"wb" - kreirati binarnu datoteku za pisanje; ako postoji, njen sadržaj se briše;

"ab" - kreirajte ili otvorite binarnu datoteku za dodavanje na kraj datoteke;

"rb+" - otvara postojeću binarnu datoteku u načinu čitanja i pisanja;

"wb+" - otvara binarnu datoteku u načinu čitanja i pisanja, postojeći fajl se briše;

"ab+" - Otvara se ili kreira binarna datoteka kako bi se ispravile postojeće informacije i dodale nove informacije na kraj datoteke.

Funkcija vraća NULL vrijednost u varijablu datoteke f ako datoteka nije uspješno otvorena. Nakon otvaranja datoteke, njen 0-ti bajt je dostupan, pokazivač datoteke je 0, čija se vrijednost pomjera za pročitani (upisani) broj bajtova dok se čita ili upisuje. Trenutna vrijednost pokazivača datoteke je broj bajta iz kojeg će se izvršiti operacija čitanja ili pisanja.

Za zatvaranje datoteku, funkcija fclose je namijenjena

int fclose(FILE *ime datoteke);

Vraća 0 ako je datoteka uspješno zatvorena, NULL u suprotnom.

Funkcija uklanjanja je za odstranjivanje datoteke.

int remove(const char *ime datoteke);

Ova funkcija uklanja datoteku pod nazivom filenema s diska. Datoteka koju treba izbrisati mora biti zatvorena. Funkcija vraća vrijednost različitu od nule ako se datoteka ne može izbrisati.

Za preimenovanje datoteke, funkcija preimenovanja je namijenjena:

int rename(const char *oldfilename, const char *newfilename);

Prvi parametar je staro ime datoteke, drugi je novi. Vraća 0 nakon uspješnog završetka programa.

Čitanje iz binarne datoteke se radi pomoću funkcije fread:

fread(void *ptr, veličina, n, FILE *ime datoteke);

Funkcija fread čita n elemenata veličine veličine iz naziva datoteke u ptr niz. Funkcija vraća broj pročitanih elemenata. Nakon čitanja iz datoteke, njen pokazivač se pomjera za n*veličine bajtova.

Snimanje u binarnu datoteku se vrši pomoću funkcije fwrite:

fwrite(const void *ptr, veličina, n, FILE *ime datoteke);

Funkcija fwrite upisuje n elemenata veličine u ime datoteke iz ptr niza. Funkcija vraća broj upisanih elemenata. Nakon što se informacija upiše u datoteku, pokazivač se pomjera za n*veličine bajtova.

Za kontrola kraja datoteke postoji feof funkcija:

int feof(FILE *ime datoteke);

Vraća vrijednost različitu od nule ako se dostigne kraj datoteke.

PRIMJER:

Kreirajte binarni fajl D:\\game\\noobs.dat i u njega upišite cijeli broj n i n realnih brojeva.

#include "stdafx.h"

#include

korištenje imenskog prostora std;

int main()

setlocale(LC_ALL, "RUS");

int n, i;

duplo a;

// kreirati binarnu datoteku u načinu pisanja

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

// unos brojevin

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

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

//petlja za unos n realnih brojeva

za (i=0; i

//unesite sljedeći realni broj

cout<<"a=";

cin>>a;

//upisuje realni broj u binarnu datoteku

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

// zatvori fajl

fclose(f);

system("pauza");

return 0;

PRIMJER:

Prikaži sadržaj binarne datoteke D:\\game\\noobs.dat kreirane u prethodnom zadatku

#include "stdafx.h"

#include

korištenje imenskog prostora std;

int main()

setlocale(LC_ALL, "RUS");

int n, i;

duplo *a;

FILE *f; //opišemo varijablu datoteke

//otvaranje postojeće binarne datoteke u načinu čitanja

//čitaj jedan cijeli broj iz datoteke u varijablu n

//izlaz n na ekran

cout<<"n="<

//dodijelimo memoriju za niz od n brojeva

a=novi dupli[n];

//čitanje n realnih brojeva iz datoteke u niz a

//izlaz niza na ekran

za (i=0; i

cout<

cout<

// zatvori fajl

fclose(f);

system("pauza");

return 0;

Binarno- sekvencijalna struktura podataka, nakon otvaranja datoteke, dostupan je prvi bajt pohranjen u njoj. Možete sekvencijalno pisati ili čitati podatke iz datoteke. Pretpostavimo da trebate izbrojati petnaesti broj, a zatim prvi. Sa serijskim pristupom to se može učiniti na sljedeći način:

int n, i;

duplo a;

FILE *f;

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

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

fclose(f);

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

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

fclose(f);

Kao što vidite, čitanje brojeva iz datoteke, a zatim ponovno otvaranje datoteke nije najpogodniji način. Mnogo je zgodnije koristiti funkciju fseek za pomicanje pokazivača datoteke na dati bajt.

int fseek(FILE *ime datoteke, dugi int pomak, int porijeklo);

Funkcija postavlja pokazivač na trenutnu poziciju datoteke F u skladu sa vrijednošću početka i pomaka. Parametar pomaka jednak je broju bajtova za koji će se pokazivač datoteke pomjeriti u odnosu na ishodište specificirano parametrom porijekla. Vrijednost parametra porijekla mora biti jedna od sljedećih vrijednosti za pomak, definiranih u zaglavlju stdio.h:

SEEK_SET - od početka fajla;

SEEK_CUR - sa trenutne pozicije;

SEEK_END - sa kraja fajla.

Funkcija vraća nulu ako je operacija uspješna, različitu od nule ako pomak ne uspije.

Funkcija fseek zapravo implementira direktan pristup bilo kojoj vrijednosti u datoteci. Trebate samo znati lokaciju (broj bajta) vrijednosti u datoteci. Razmotrite upotrebu direktnog pristupa u binarnim datotekama koristeći primjer rješavanja sljedećeg problema.

PRIMJER

U binarnoj datoteci D:\\game\\noobs.dat kreiranoj ranije, zamijenite najveći i najmanji realni broj.

Algoritam za rješavanje problema sastoji se od sljedećih koraka:

    čitanje realnih vrijednosti iz datoteke u niz a.

    pretražite u nizu a maksimalne (max) i minimalne (min) vrijednosti i njihove brojeve (imax, imin).

    pomeranje pokazivača fajla na maksimalnu vrednost i pisanje min.

    pomeranje pokazivača fajla na minimalnu vrednost i pisanje max.

Ispod je tekst programa za rješavanje problema s komentarima.

#include "stdafx.h"

#include

korištenje imenskog prostora std;

int main()

setlocale(LC_ALL, "RUS");

int n, i, imax, imin;

duplo *a, max, min;

FILE *f;

//otvaranje datoteke u načinu čitanja/pisanja

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

//čitanje iz datoteke u varijablu n broj

//realni brojevi u datoteci

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

cout<<"n="<

//dodijeliti memoriju za pohranjivanje realnih brojeva,

//koji će biti pohranjen u nizu a

a=novi dupli[n];

//čitanje iz datoteke u niz i realne brojeve

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

//tražimo maksimalne i minimalne elemente

//u nizu a i njihovim indeksima

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

ako (a[i]>max)

max=a[i];

ako (a[i]

min=a[i];

// kreće se pokazivač to maksimum element

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

//snimanje min umjesto maksimalnog elementa datoteke

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

// kreće se pokazivač to minimum element

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

//zabilježite maksimum umjesto minimalnog elementa datoteke

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

//zatvaranje fajla

fclose(f);

// slobodna memorija

obriši[ ]a;

system("pauza");

Tekstualne datoteke

Razmotrimo rad sa tekstualnom datotekom u C koristeći primjer. Kreirajte tekstualnu datoteku na disku C pod nazivom TextFile.txt. Unesite sljedeće redove u ovu datoteku:

Niz_1 123 Niz_11, 456
String_2
String_3

Sačuvajte fajl.

A ovo je kod za C program koji otvara naš fajl i čita redove iz njega:

/* *Autor: @author Subbotin B.P..h> #include #define LEN 50 int main(void) ( puts("Operacije tekstualnih datoteka"); char cArray; FILE *pTextFile = fopen("C:\\TextFile.txt", "r"); if(pTextFile == NULL) ( puts("Problemi"); return EXIT_FAILURE; ) while(fgets(cArray, LEN, pTextFile) != NULL) ( printf("%s", cArray); ) fclose(pTextFile); return EXIT_SUCCESS; )

Da otvorite tekstualnu datoteku u C, koristite funkciju fopen:

FILE *pTextFile = fopen("C:\\TextFile.txt", "r");

Prvi argument funkcije fopen ukazuje na datoteku, a drugi kaže da je datoteka otvorena za čitanje iz nje.

Čitamo redove koristeći fgets funkciju:

fgets(cArray, LEN, pTextFile);

Prvi argument funkcije fgets ukazuje na niz znakova u koji će primljeni nizovi biti pohranjeni, drugi argument je maksimalan broj znakova za čitanje, treći je naš fajl.

Nakon što završite rad sa fajlom, morate ga zatvoriti:

fclose(pTextFile);

Dobijamo:

Prolaze i ruska slova u redovima.

Inače, napravio sam ovaj program u Eclipse-u. Možete vidjeti kako raditi sa C/C++ u Eclipseu.

Dakle, otvorili smo i pročitali podatke iz tekstualne datoteke.

Sada naučimo kako programski kreirati tekstualnu datoteku i zapisati podatke u nju.

/* Autor: @author Subbotin B.P..h> #include int main(void) ( FILE *pTextFile = fopen("C:\\TextFileW.txt", "w"); char *cString = "Ovo je niz"; char cNewLine = "\n"; int nVal = 123 ; if(pTextFile == NULL) ( puts("Problemi"); return EXIT_FAILURE; ) fprintf(pTextFile, "%s%c", cString, cNewLine); fprintf(pTextFile, "%d", nVal); return EXIT_SUCCESS ;)

Kreirajte tekstualnu datoteku da u nju upišete podatke:

FILE *pTextFile = fopen("C:\\TextFileW.txt", "w");

ako datoteka već postoji, biće otvorena i svi podaci će biti izbrisani iz nje.

C-string cString i broj nVal program upisuje u tekstualnu datoteku. cNewLine je samo prijelom reda.

Zapisujemo podatke u tekstualnu datoteku koristeći fprintf funkciju:

fprintf(pTextFile, "%s%c", cString, cNewLine);

prvi argument ovdje je naš fajl, drugi je niz formata, treći ili više je broj argumenata potrebnih za ovaj format.

Radi lakšeg rukovanja, informacije u uređajima za pohranu pohranjuju se u obliku datoteka.

Datoteka je imenovana oblast vanjske memorije koja je dodijeljena za pohranjivanje niza podataka. Podaci sadržani u datotekama su najrazličitije prirode: programi na algoritamskom ili mašinskom jeziku; početni podaci za rad programa ili rezultati izvođenja programa; proizvoljni tekstovi; grafike itd.

Direktorij (fascikla, direktorij) - imenovana kolekcija bajtova na mediju za pohranu koji sadrži nazive poddirektorija i datoteka, koji se koriste u sistemu datoteka za pojednostavljenje organizacije datoteka.

sistem podataka je funkcionalni dio operativnog sistema koji pruža operacije nad datotekama. Primeri sistema datoteka su FAT (FAT - Tabela alokacije datoteka, tabela alokacije datoteka), NTFS, UDF (koristi se na CD-ovima).

Postoje tri glavne verzije FAT-a: FAT12, FAT16 i FAT32. Razlikuju se po bitnosti zapisa u strukturi diska, tj. broj bitova dodijeljenih za pohranjivanje broja klastera. FAT12 se uglavnom koristi za flopi diskove (do 4 KB), FAT16 za male diskove, FAT32 za FLASH diskove velikog kapaciteta (do 32 GB).

Razmotrite strukturu sistema datoteka koristeći FAT32 kao primjer.

FAT32 struktura datoteke

Eksterni memorijski uređaji u sistemu FAT32 nisu bajt, već blok adresiranje. Informacije se upisuju na eksterni memorijski uređaj u blokovima ili sektorima.

Sektor - minimalna adresabilna jedinica za skladištenje informacija na eksternim uređajima za skladištenje. Tipično, veličina sektora je fiksna na 512 bajtova. Da bi se povećao adresni prostor eksternih memorijskih uređaja, sektori se kombinuju u grupe koje se nazivaju klasteri.

Klaster je asocijacija više sektora, koji se mogu smatrati nezavisnom jedinicom sa određenim svojstvima. Glavno svojstvo klastera je njegova veličina, mjerena brojem sektora ili brojem bajtova.

FAT32 sistem datoteka ima sljedeću strukturu.

Klasteri koji se koriste za pisanje fajlova su numerisani počevši od 2. U pravilu, klaster #2 koristi osnovni direktorijum, a počevši od klastera #3, pohranjuje se niz podataka. Sektori koji se koriste za pohranjivanje informacija iznad korijenskog direktorija nisu grupirani.
Minimalna veličina datoteke na disku je 1 klaster.

Sektor za pokretanje počinje sa sljedećim informacijama:

  • EB 58 90 - bezuslovna grana i potpis;
  • 4D 53 44 4F 53 35 2E 30 MSDOS5.0;
  • 00 02 - broj bajtova u sektoru (obično 512);
  • 1 bajt - broj sektora u klasteru;
  • 2 bajta - broj rezervnih sektora.

Osim toga, sektor za pokretanje sadrži sljedeće važne informacije:

  • 0x10 (1 bajt) – broj FAT tabela (obično 2);
  • 0x20 (4 bajta) - broj sektora na disku;
  • 0x2C (4 bajta) – broj klastera korijenskog direktorija;
  • 0x47 (11 bajtova) – oznaka volumena;
  • 0x1FE (2 bajta) - Potpis sektora za pokretanje (55 AA).

Sektor informacija o sistemu datoteka sadrži:

  • 0x00 (4 bajta) – potpis (52 52 61 41 );
  • 0x1E4 (4 bajta) – potpis (72 72 41 61 );
  • 0x1E8 (4 bajta) – broj slobodnih klastera, -1 ako nije poznato;
  • 0x1EC (4 bajta) – broj posljednjeg snimljenog klastera;
  • 0x1FE (2 bajta) - potpis (55 AA).

FAT tabela sadrži informacije o stanju svakog klastera na disku. Donja 2 bajta FAT tabele pohranjuju F8 FF FF 0F FF FF FF FF (odgovara stanju klastera 0 i 1, fizički odsutan). Nadalje, stanje svakog klastera sadrži broj klastera u kojem se nastavlja trenutni fajl ili sljedeće informacije:

  • 00 00 00 00 – klaster je slobodan;
  • FF FF FF 0F je kraj trenutnog fajla.
  • 8 bajtova - naziv datoteke;
  • 3 bajta - ekstenzija datoteke;

Korijenski direktorij sadrži skup 32-bitnih zapisa informacija za svaki fajl koji sadrži sljedeće informacije:

Kada radite sa dugim nazivima datoteka (uključujući ruska imena), naziv datoteke je kodiran u UTF-16 sistemu kodiranja. U ovom slučaju, 2 bajta se dodjeljuju za kodiranje svakog znaka. U ovom slučaju, naziv datoteke je napisan u obliku sljedeće strukture:

  • 1 bajtova sekvenca;
  • 10 bajtova sadrži donjih 5 znakova imena datoteke;
  • 1 bajt atribut;
  • 1 bajt rezerviran;
  • 1 bajt - kontrolna suma DOS imena;
  • 12 bajtova sadrže donja 3 znaka imena datoteke;
  • 2 bajta – broj prvog klastera;
  • preostali znakovi dugog imena.

Rad sa datotekama u C

Za programera, otvorena datoteka je predstavljena kao niz podataka koji se čitaju ili pišu. Kada se datoteka otvori, ona je povezana sa I/O tok. Izlazne informacije se upisuju u tok, ulazne informacije se čitaju iz toka.

Kada se tok otvori za I/O, on je povezan sa standardnom strukturom tipa FILE, koja je definirana u stdio.h. Struktura FILE sadrži potrebne informacije o datoteci.

Otvaranje datoteke se vrši pomoću fopen() funkcije, koja vraća pokazivač na strukturu tipa FILE, koja se može koristiti za naredne operacije na datoteci.

FILE *fopen(ime, tip);


ime je ime datoteke koja se otvara (uključujući putanju),
tip je pokazivač na niz znakova koji definiraju kako se pristupa datoteci:
  • "r" - otvori datoteku za čitanje (datoteka mora postojati);
  • "w" - otvara praznu datoteku za pisanje; ako datoteka postoji, njen sadržaj se gubi;
  • "a" - otvoren fajl za pisanje do kraja (za dodavanje); datoteka se kreira ako ne postoji;
  • "r+" - otvorena datoteka za čitanje i pisanje (datoteka mora postojati);
  • "w+" - otvara praznu datoteku za čitanje i pisanje; ako datoteka postoji, njen sadržaj se gubi;
  • "a+" - otvorite datoteku za čitanje i dodavanje, ako datoteka ne postoji, kreira se.

Povratna vrijednost je pokazivač na otvoreni tok. Ako se pronađe greška, vraća se NULL.

Funkcija fclose() zatvara tok ili tokove povezane s datotekama otvorenim pomoću fopen(). Tok koji treba zatvoriti je određen argumentom funkcije fclose().

Povratna vrijednost: vrijednost 0 ako je stream uspješno zatvoren; EOF konstanta ako je došlo do greške.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

#include
int main() (
FILE *fp;
char name = "my.txt" ;
if ((fp = fopen(ime, "r" )) == NULL )
{
printf( "Nije moguće otvoriti fajl");
getchar();
return 0;
}
// otvaranje datoteke uspješno
... // potrebne radnje na podacima
fclose(fp);
getchar();
return 0;
}

Čitanje znaka iz datoteke:

char fgetc(stream);


Argument funkcije je pokazivač na tok tipa FILE. Funkcija vraća kod pročitanog znaka. Ako se dostigne kraj datoteke ili dođe do greške, vraća se EOF konstanta.

Upisivanje karaktera u datoteku:

fputc(znak, tok);

Argumenti funkcije su znak i pokazivač na tok tipa FILE. Funkcija vraća kod pročitanog znaka.

Funkcije fscanf() i fprintf() slične su funkcijama scanf() i printf(), ali rade na datotekama podataka i imaju pointer kao prvi argument.

fscanf(stream, "InputFormat" , args);

Za programera, otvorena datoteka je predstavljena kao niz podataka koji se čitaju ili pišu. Kada se datoteka otvori, ona je povezana sa I/O tok . Izlazne informacije se upisuju u tok, ulazne informacije se čitaju iz toka.

Kada se tok otvori za I/O, on je povezan sa standardnom strukturom tipa FILE, koja je definirana u stdio.h. Struktura FILE sadrži potrebne informacije o datoteci.

Otvaranje datoteke se vrši pomoću fopen() funkcije, koja vraća pokazivač na strukturu tipa FILE, koja se može koristiti za naredne operacije s datotekom.

FILE *fopen(ime, tip);

ime je ime datoteke koja se otvara (uključujući putanju),
type - pokazivač na niz znakova koji definiraju kako se pristupa datoteci:

· "r" - otvori datoteku za čitanje (datoteka mora postojati);

· "w" - otvara praznu datoteku za pisanje; ako datoteka postoji, njen sadržaj se gubi;

· "a" - otvoren fajl za pisanje do kraja (za dodavanje); datoteka se kreira ako ne postoji;

· "r+" - otvara fajl za čitanje i pisanje (fajl mora postojati);

· "w+" - otvara praznu datoteku za čitanje i pisanje; ako datoteka postoji, njen sadržaj se gubi;

· "a+" - otvara fajl za čitanje i dodavanje, ako fajl ne postoji, kreira se.

Povratna vrijednost je pokazivač na otvoreni tok. Ako se pronađe greška, vraća se NULL.

Funkcija fclose() zatvara tok ili tokove povezane s datotekama otvorenim pomoću fopen(). Tok koji treba zatvoriti je određen argumentom funkcije fclose().

Povratna vrijednost: vrijednost 0 ako je stream uspješno zatvoren; EOF konstanta ako je došlo do greške.

#include
int main()

char name="my.txt";

if(fp = fopen(ime, "r")!=NULL)

// da li je bilo moguće otvoriti fajl?
... // potrebne radnje na podacima

else printf("Ne mogu otvoriti fajl");

Čitanje znaka iz datoteke:

char fgetc(stream);

Argument funkcije je pokazivač na tok tipa FILE. Funkcija vraća kod pročitanog znaka. Ako se dostigne kraj datoteke ili dođe do greške, vraća se EOF konstanta.
Upisivanje karaktera u datoteku:

fputc(znak, tok);

Argumenti funkcije su znak i pokazivač na tok tipa FILE. Funkcija vraća kod pročitanog znaka.

Funkcije fscanf() i fprintf() slične su funkcijama scanf() i printf(), ali rade na datotekama podataka i imaju pointer kao prvi argument.

fscanf(stream, "Input Format", argumenti);
fprintf(stream, "Output Format", argumenti);

Funkcije fgets() i fputs() su za string I/O, analogne su funkcijama gets() i puts() za rad sa datotekama.

fgets(pokazivač na niz, broj znakova, tok);

Znakovi se čitaju iz toka dok se ne pročita znak novog reda "\n", koji je uključen u string, ili dok kraj toka nije EOF ili dok se ne pročita maksimalan broj znakova. Rezultat se stavlja u string pokazivač i završava nultom karakterom "\0". Funkcija vraća adresu niza.

fputs(Pointer to String, stream);

Kopira string u tok sa trenutne pozicije. Završni null karakter se ne kopira.
Primjer Unesite broj i sačuvajte ga u s1.txt fajlu. Pročitajte broj iz datoteke s1.txt, povećajte ga za 3 i sačuvajte u s2.txt datoteci.

I/O mehanizam koji je razvio , ne odgovara opšteprihvaćenom objektno orijentisanom stilu programiranja danas, osim toga, aktivno koristi operacije pokazivača, koje se smatraju potencijalno nebezbednim u modernim okruženjima bezbednog izvršavanja koda. Alternativa za razvoj aplikacija je standardni mehanizam I/O klase koji obezbjeđuje standard jezika C++.

Otvaranje fajlova

Najčešće korištene klase su ifstream za čitanje, ofstream za pisanje i fstream za modificiranje datoteka.

Sve navojne I/O klase indirektno su izvedene iz zajedničkog pretka ios-a, u potpunosti nasljeđujući njegovu funkcionalnost. Na primjer, open_mode nabrojani član podataka specificira način otvaranja datoteke, koji je definiran na sljedeći način:

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

Ispod su moguće vrijednosti zastava i njihova namjena.

Na primjer, da biste otvorili datoteku pod nazivom test.txt za čitanje binarnih podataka, napisali biste:

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

Logički OR operator (|) vam omogućava da sastavite režim sa bilo kojom kombinacijom zastavica. Da prilikom otvaranja datoteke pisanjem ne biste slučajno prepisali postojeći fajl istog imena, morate koristiti sljedeći obrazac:

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

Pretpostavlja se da je odgovarajući fajl zaglavlja povezan sa projektom:

#include

Da biste provjerili je li datoteka uspješno otvorena, možete koristiti konstrukciju

If (!file) ( // Rukovanje greškom otvaranja datoteke)

Operatori uključivanja i ekstrakcije

Poništeno u klasama rukovanja datotekama uključi operatera (<<) записывает данные в файловый поток. Как только вы открыли файл для записи, можно записывать в него текстовую строку целиком:

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

Također možete napisati tekstualni niz u dijelovima:

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

Naredba endl završava unos u liniji s povratnim znakom:

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

Koristeći operator uključivanja, lako je zapisati vrijednosti varijabli ili elemenata niza u datoteku:

Offstream fajl("Temp.txt"); char buff = "Tekstualni niz sadrži varijable"; int vx = 100; float pi = 3,14159; fajl<< buff << endl << vx << endl << pi << endl;

Kao rezultat izvršenja koda, generiraju se tri reda tekstualne datoteke Temp.txt:

Tekstualni niz sadrži varijable 100 3.14159

Imajte na umu da se numeričke vrijednosti zapisuju u datoteku kao tekstualni nizovi, a ne binarne vrijednosti.

operator ekstrakcije(>>) radi suprotno. Čini se da da biste izdvojili znakove iz datoteke Temp.txt koja je ranije napisana, trebate napisati sljedeći kod:

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

Međutim, operator ekstrakcije će se zaustaviti na prvom graničniku (razmak, tabulator ili novi red) na koji naiđe. Dakle, prilikom raščlanjivanja rečenice "Tekstni niz sadrži varijable", samo će riječ "Text" biti upisana u niz buff , razmak se zanemaruje, a riječ "niz" će postati vrijednost cjelobrojne varijable vx i koda izvršenje će se "pokvariti" uz neizbježno kršenje strukture podataka. Zatim, kada govorimo o klasi ifstream, pokazat ćemo kako pravilno organizirati čitanje datoteke iz prethodnog primjera.

ifstream klasa: čitanje datoteka

Kao što naziv implicira, klasa ifstream je dizajnirana za unos toka datoteka. Glavne metode klase su navedene u nastavku. Većina njih je naslijeđena iz istream klase i preopterećena roditeljskom funkcionalnošću. Na primjer, funkcija get, ovisno o parametru poziva, može pročitati ne samo jedan znak, već i blok znakova.

Sada je jasno kako trebate modificirati prethodni primjer tako da korištenje operatora ekstrakcije podataka daje očekivani rezultat:

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

Getline metoda će pročitati prvi red datoteke do kraja, a >> operator će dodijeliti vrijednosti varijablama.

Sljedeći primjer pokazuje dodavanje podataka u tekstualnu datoteku, a zatim čitanje cijele datoteke. Petlja while (1) se koristi umjesto while(!file2.eof()) iz razloga o kojima se govori u .

#include #include korištenje imenskog prostora std; int main() ( izvanstream fajl; file.open("test.txt",ios::out|ios::app); if (!file) ( 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; }

Sljedeći primjer se kreće kroz čitanje redova iz datoteke test.txt i njihovo prikazivanje na konzoli.

#include #include korištenje imenskog prostora std; int main() ( ifstream datoteka; // kreiraj datoteku objekta toka file.open("test.txt"); // otvori datoteku za čitanje if (!file) return 1; // povratak na grešku otvaranja char str; / / statički bafer linija // Čitanje i prikaz linija u petlji do eof while (!file.getline(str, sizeof(str)).eof()) cout<< str << endl; // вывод прочитанной строки на экран cin.sync(); cin.get(); return 0; }

Ovaj kod pod Windows OS-om također ovisi o prisutnosti znaka za novi red u posljednjem redu datoteke, bilo bi pouzdanije učiniti ovo:

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

Eksplicitni pozivi metodama open i close su opcioni. Zaista, pozivanje konstruktora s argumentom omogućava vam da odmah otvorite datoteku, u trenutku kada je kreiran objekt toka datoteke:

ifstream fajl("test.txt");

Umjesto metode close, možete koristiti operator delete, koji će automatski pozvati destruktor objekta datoteke i zatvoriti datoteku. Kod petlje while pruža ispravnu provjeru kraja datoteke.

ofstream klasa: pisanje datoteka

Ofstream klasa je dizajnirana za izlaz podataka iz toka datoteka. Glavne metode ove klase su navedene u nastavku.

Ranije opisani operator uključivanja pogodan je za organiziranje pisanja u tekstualnu datoteku:

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

Binarnosti

U principu, binarni podaci se serviraju kao tekstualni podaci. Razlika je u tome što ako su binarni podaci zapisani u određenoj logičkoj strukturi, onda se moraju pročitati iz datoteke u varijablu istog tipa strukture.

Prvi parametar metoda upisivanja i čitanja (adresa bloka za upisivanje/čitanje) mora biti tipa pokazivača znakova char *, pa je potrebno eksplicitno konvertovati tip adrese void * strukture. Drugi parametar specificira da binarni blokovi datoteke imaju konstantnu veličinu bajta bez obzira na stvarnu dužinu zapisa. Sljedeći dodatak daje primjer kako kreirati i prikazati podatke u jednostavnoj bilježnici. Zapisi datoteke se zatim uzastopno čitaju i prikazuju na konzoli.

#include #include #include korištenje imenskog prostora std; struct Notes ( // struktura podataka bilježnice char Ime; // puno ime char Telefon; // telefon int Dob; // starost); int main() ( setlocale(LC_ALL, "ruski"); Bilješke Note1= ("Grozny Ioann Vasilyevich", "nije instalirano", 60); Bilješke Note2= ("Godunov Boris Fedorovič", "095-111-2233 ", 30 ); Notes Note3= ( "Petar Romanov ", "812-333-2211 ", 20 ); ofstream ofile("Notebook.dat", ios::binary); ofile.write((char*)&Note1, sizeof ( Bilješke)); // 1. blok ofile.write((char*)&Note2, sizeof(Notes)); // 2. blok ofile.write((char*)&Note3, sizeof(Notes)); / / 3. blok ofile. close(); // zatvori napisanu datoteku ifstream ifile("Notebook.dat", ios::binary); Notes Note; // strukturirana varijabla char str; // statički string buffer // Čitanje i prikaz linija u petlji dok eof while (!ifile.read((char*)&Note, sizeof(Notes)).eof()) ( sprintf(str, "%s\tBody: %s\tAge: %d" , Note.Name, Note. Telefon, Napomena. Starost); cout<< str << endl; } ifile.close(); // закрыть прочитанный файл cin.sync(); cin.get(); return 0; }

Kao rezultat izvršavanja ovog koda, binarna datoteka Notebook.dat se formira od tri bloka od 80 bajtova svaki (pod pretpostavkom da su znakovi jednobajtni). Naravno, možete koristiti druge metode strujanja i izvršiti bilo koju operaciju na poljima određene strukture podataka.

fstream klasa: slučajni pristup fajlu

Pretpostavimo da je u našoj bilježnici skupljeno 100 unosa, a mi želimo da izbrojimo 50. Naravno, možete organizirati petlju i čitati sve zapise od prvog do zadanog. Očigledno je ciljanije rješenje postaviti pokazivač pozicije pos datoteke direktno na unos 50 i pročitati ga:

ifstream ifile("Notebook.dat", ios::binary); int pos = 49 * sizeof(Napomene); ifile traži(pos); // traži 50. unos Notes Note; //Napomene - gore opisana struktura "zapisa" ifile.read((char*)&Note, sizeof(Notes));

Takve operacije pretraživanja su efikasne ako se datoteka sastoji od zapisa poznate i konstantne veličine. Da biste zamijenili sadržaj proizvoljnog unosa, morate otvoriti izlazni tok u modificiranom modu:

Ofstream ofile("Notebook.dat", ios::binary | ios::ate); int pos = 49 * sizeof(Napomene); ofile seekp(pos); // traži 50. notu Notes Note50 = ("Jeljcin Boris Nikolajevič", "095-222-3322", 64); ofile.write((char*)&Note, sizeof(Notes)); // zamjena

Ako ne navedete oznaku ios::ate (ili ios::app), onda kada otvorite binarnu datoteku Notebook.dat, njen prethodni sadržaj će biti izbrisan!

Konačno, moguće je istovremeno otvoriti datoteku za čitanje/pisanje, koristeći metode koje naslijeđuje fstream streaming klasa od svojih prethodnika. Budući da je klasa fstream izvedena iz istream i ostream (roditelji ifstreama i ofstreama, respektivno), sve prethodno spomenute metode postaju dostupne aplikaciji.

Sljedeći primjer zamjenjuje prvi i treći unos u datoteci Notebook.dat.

#include #include #include korištenje imenskog prostora std; struct Notes ( char Ime; char Telefon; int Age; ); int main() ( setlocale(LC_ALL, "Russian"); Notes Note1, Note3; // Otvorite datoteku za istovremeno čitanje/pisanje fstream file("Notebook.dat", ios::binary | ios::in | ios:: out); file.seekg(2 * sizeof(Notes)); // pronaći i pročitati Note3 file.read((char*)&Note3, sizeof(Notes)); file.seekg(0); // pronaći i pročitati Note1 file.read((char*)&Note1, sizeof(Notes)); file.seekg(0); // Note1<== 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; }

Oznake ios::in i ios::out moraju biti specificirane u konstruktoru objekta datoteke kako bi se omogućile istovremene operacije čitanja i pisanja. Kao rezultat izvršavanja ovog koda, prvi i treći zapis binarne datoteke Notebook.dat će biti zamijenjeni.

Postoje dodatni primjeri na ovu temu.

Top Related Articles