This shows you the differences between two versions of the page.
programare-cc:laboratoare:11 [2020/10/06 17:40] 127.0.0.1 external edit |
programare-cc:laboratoare:11 [2023/12/20 14:41] (current) mihai.nan [Problema 1 (Rezolvata)] |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ===== Laboratorul 11. ===== | + | ===== Laboratorul 11. Fişiere text. Argumente în linia de comandă ===== |
+ | |||
+ | |||
+ | În acest laborator veţi învăţa să: | ||
+ | * Citiţi şi scrieţi date din fişiere text. | ||
+ | * Trimiteţi şi folosiţi argumente în linia de comandă. | ||
+ | |||
+ | ====Fişiere text==== | ||
+ | Pentru a realiza operaţii cu fişiere text se folosesc funcţii şi structuri definite în stdio.h: | ||
+ | |||
+ | **FILE** este o structură ce conţine informaţiile necesare controlării unui fişier. | ||
+ | |||
+ | ''FILE * fopen ( const char * filename, const char * mode )'' asociază fişierul cu o structură FILE şi întoarce un pointer la această | ||
+ | structură. Dacă fişierul nu există sau nu a putut fi deschis, se va întoarce NULL. mode reprezintă modul de access dorit: | ||
+ | * **"r"** deschide fişierul pentru citire; fişierul trebuie să existe. | ||
+ | * **"w"** creează un fişier gol pentru scriere; dacă există deja un fişier cu acelaşi nume, conţinutul lui este şters şi este tratat ca un fişier gol. | ||
+ | * **"a"** adaugă datele la sfârşitul fişierului; fişierul este creat dacă nu există. | ||
+ | * **"r+"** deschide un fişier atât pentru scriere, cât şi pentru citire; fişierul trebuie să existe. | ||
+ | * **"w+"** creează un fişier gol atât pentru scriere, cât şi pentru citire; dacă există deja un fişier cu acelaşi nume, conţinutul lui este şters şi este tratat ca un fişier gol. | ||
+ | * **"a+"** deschide un fişier pentru citire şi adăugare la sfârşit; se poate citi de la orice poziţie din fişier, însă scrierea se face doar la sfârşit; fişierul este creat dacă nu există | ||
+ | |||
+ | ''int fclose ( FILE * file )'' închide fişierul asociat cu structura file şi îl dezasociază. | ||
+ | |||
+ | Funcţii de citire şi afişare pentru fişiere: | ||
+ | * ''int fgetc ( FILE * f );'' întoarce următorul caracter din fişier convertit la int sau EOF dacă sa întâlnit sfârşitul de fişier sau o eroare. | ||
+ | * ''char *fgets ( char *buf, int nmax, FILE * f )'' citeşte caractere din fişier până cănd se întâlneşte '\n' (este şi el adăugat la şir) sau până când sau citit nmax 1 caractere. | ||
+ | * ''int fputc ( int c, FILE * f )'' scrie caracterul c în fişier; funcţia întoarce caracterul scris, în caz de success sau EOF altfel. | ||
+ | * ''int fputs ( char *buf, FILE *f )'' scrie şirul buf în fişier; în caz de eroare se întoarce EOF, altfel se întoarce o valoare nonnegativă. | ||
+ | * ''int fscanf ( FILE *f, const char * format, ... )'' | ||
+ | * ''int fprintf ( FILE *f, const char * format, ... )'' | ||
+ | |||
+ | ====Argumente în linia de comandă==== | ||
+ | Pentru a specifica argumente în linia de comandă, antetul funcţiei main va trebui să fie de forma: | ||
+ | <code c> int main ( int argc, char *argv[] ); </code> | ||
+ | **argc** reprezintă numărul de argumente, iar **argv** vectorul de pointeri la argumente (şiruri de caractere). Primul argument argv[ 0 ] este | ||
+ | întotdeauna **numele executabilului**. | ||
+ | Pentru a seta argumentele din CodeBlocks va trebui să adăugaţi fişierul sursă la un proiect şi apoi să selectaţi: Project > Set programs' | ||
+ | arguments. | ||
+ | |||
+ | |||
+ | |||
+ | ==== Problema 1 (Rezolvata) ==== | ||
+ | ---- | ||
+ | Scrieţi un program care citeşte conţinutul unui fişier text myfile.txt şi îl trimite către stdout. | ||
+ | |||
+ | ==Date de intrare== | ||
+ | Fişierul text myfile.txt | ||
+ | |||
+ | ==Date de ieşire== | ||
+ | Conţinutul fisierului de intrare | ||
+ | |||
+ | ==Rezolvare== | ||
+ | <code c> | ||
+ | #include <stdio.h> | ||
+ | #define BUFMAX 1005 | ||
+ | |||
+ | int main(int argc, char **argv) | ||
+ | { | ||
+ | FILE *pFile; | ||
+ | char buffer[BUFMAX]; | ||
+ | |||
+ | pFile = fopen("myfile.txt" , "r"); | ||
+ | if (pFile == NULL) { | ||
+ | printf("Nu s-a putut deschide fisierul"); | ||
+ | return 1; | ||
+ | } | ||
+ | |||
+ | while (fgets(buffer, BUFMAX, pFile) != NULL) { | ||
+ | printf("%s", buffer); | ||
+ | } | ||
+ | fclose(pFile); | ||
+ | return 0; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | |||
+ | ==== Problema 2 (Rezolvata) ==== | ||
+ | Scrieţi un program pentru concatenarea mai multor fişiere text întrun fişier destinaţie. Programul va primi numele fişierelor ca | ||
+ | argumente în linia de comandă, în următoarea ordine: destinatie $sursa_1, sursa_2 \dots sursa_n$. | ||
+ | |||
+ | ==Date de intrare== | ||
+ | Fişierele de intrare $sursa_1, sursa_2 \dots sursa_n$. | ||
+ | ==Date de ieşire== | ||
+ | Fişierele de intrare concatenate în fişierul destinaţie. | ||
+ | ==Rezolvare== | ||
+ | <code c> | ||
+ | #include <stdio.h> | ||
+ | #define BUFMAX 1005 | ||
+ | |||
+ | int main(int argc, char *argv[]) | ||
+ | { | ||
+ | FILE *dest, *src; | ||
+ | int i; | ||
+ | char buffer[BUFMAX]; | ||
+ | dest = fopen(argv[1], "w"); | ||
+ | if (!dest) | ||
+ | { | ||
+ | fprintf(stderr, "Eroare! Nu am putut deschide fisierul destinatie!\n"); | ||
+ | return 0; | ||
+ | } | ||
+ | for (i = 2; i < argc; ++i) | ||
+ | { | ||
+ | src = fopen(argv[i], "r"); | ||
+ | if (!src) | ||
+ | { | ||
+ | fprintf(stderr, "Eroare! Nu am putut deschide fisierul sursa (%d)!\n", i); | ||
+ | return 0; | ||
+ | } | ||
+ | while (fgets(buffer, BUFMAX, src) != NULL) | ||
+ | fputs(buffer, dest); | ||
+ | fclose(src); | ||
+ | } | ||
+ | fclose(dest); | ||
+ | return 0; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | ====Problema 3A==== | ||
+ | Scrieţi un program pentru căutarea unui şir dat întrun fişier text şi afişarea liniilor care conţin şirul dat. Numele fişierului şi şirul căutat | ||
+ | vor fi trimise ca argumente în linia de comandă, în această ordine. | ||
+ | |||
+ | ==Date de intrare (argumente în linia de comandă)== | ||
+ | Numele fişierului in care se realizează cautarea | ||
+ | Stringul căutat | ||
+ | |||
+ | ==Date de ieşire (consolă)== | ||
+ | Liniile ce conţin şirul căutat | ||
+ | |||
+ | ==Exemplu== | ||
+ | Pentru a căuta în fişierul input.txt stringul vacanta: | ||
+ | |||
+ | **./executabil input.txt vacanta** | ||
+ | |||
+ | ^ input.txt ^ stdout ^ | ||
+ | |Mai e putin si vine vacanta \\ Mie nu imi plac pointerii dar iubesc vacanta \\ Abia astept sesiunea \\ Haideti sa mergem la un suc chiar acum \\ Cine stie sa se dea cu placa de snowboard ?! \\ Vacanta asta merg la Predeal si ma dau cu placa :) \\ Ma asteapta o sesiune infernala :-( \\ Vine vacanta cu trenul din Franta ... \\ La multi ani 2021 | Mai e putin si vine vacanta \\ Mie nu imi plac pointerii dar iubesc vacanta \\ Vine vacanta cu trenul din Franta ... | | ||
+ | |||
+ | |||
+ | ====Problema 3B==== | ||
+ | Scrieţi un program pentru căutarea unui şir dat întrun fişier text şi afişarea liniilor care conţin şirul dat. Numele fişierului şi şirul căutat vor fi | ||
+ | trimise ca argumente în linia de comandă, în această ordine. Adăugaţi programului posibilitatea de a primi ca argumente şi una sau mai multe | ||
+ | dintre următoarele opţiuni (ultimele 2 argumente vor fi întotdeauna numele fişierului şi şirul căutat): | ||
+ | i ignoră diferenţa dintre litere mici şi litere mari. | ||
+ | n afişează şi numerele liniilor din fişier care conţin şirul căutat. | ||
+ | c afişează numărul de linii în care sa găsit şirul căutat. | ||
+ | Aceste 3 argumente pot apărea în orice ordine. | ||
+ | |||
+ | ==Date de intrare (argumente în linia de comandă)== | ||
+ | Numele fişierului în care se realizează căutarea | ||
+ | Parametrii pentru căutare | ||
+ | Stringul căutat | ||
+ | |||
+ | ==Date de ieşire (consolă)== | ||
+ | Liniile ce conţin şirul căutat | ||
+ | Numărul liniei din fişierul sursă | ||
+ | Numărul de linii în care sa găsit şirul căutat | ||
+ | |||
+ | ==Exemplu== | ||
+ | Dacă, căutăm în fişierul input.txt stringul vacanta: | ||
+ | |||
+ | **./executabil c i n input.txt vacanta** | ||
+ | |||
+ | ^ input.txt ^ stdout ^ | ||
+ | |Mai e putin si vine vacanta \\ Mie nu imi plac pointerii dar iubesc vacanta \\ Abia astept sesiunea \\ Haideti sa mergem la un suc chiar acum \\ Cine stie sa se dea cu placa de snowboard ?! \\ Vacanta asta merg la Predeal si ma dau cu placa :) \\ Ma asteapta o sesiune infernala :-( \\ Vine vacanta cu trenul din Franta ... \\ La multi ani 2014 | [1] Mai e putin si vine vacanta \\ [2] Mie nu imi plac pointerii dar iubesc vacanta \\ [6] Vacanta asta merg la Predeal si ma dau cu placa :) \\ [8] Vine vacanta cu trenul din Franta ... \\ Numar total de linii: 4 | | ||
+ | |||
+ | ====Problema 4==== | ||
+ | Se dă un fişier în care este memorată o tabelă de codificare, sub forma: | ||
+ | caracter_de_codificat caracter_codificat \n | ||
+ | Să se scrie un program care primeşte ca argumente în linia de comandă numele fişierului conţinând tabela de codificare, numele | ||
+ | fişierului de codificat şi numele fişierului în care se va scrie codificarea (în această ordine) şi codifică fişierul primit conform codului. | ||
+ | Presupunem un fişier tabela_de_codare.in care reţine următoarele corespondenţe: | ||
+ | ^ tabela_de_codare.in ^ | ||
+ | | a b \\ b c \\ c d \\ d e \\ e f \\ f g \\ g h \\ h i \\ i j \\ j k \\ k l \\ l m \\ m n \\ n o \\ o p | | ||
+ | |||
+ | ==Date de intrare (input.txt)== | ||
+ | Textul original | ||
+ | |||
+ | ==Date de ieşire (output.txt)== | ||
+ | Textul modificat | ||
+ | |||
+ | ==Exemplu== | ||
+ | Aplicăm algoritmul de codare pe fişierul input.txt şi vom obţine un fişier output.txt. | ||
+ | |||
+ | |||
+ | **./executabil tabela_de_codare.in input.txt output.txt** | ||
+ | |||
+ | ^ Intrare (input.txt ) ^ Ieşire (output.txt) ^ | ||
+ | | Abia astept examenul de PL \\ In vacanta dorm. Dorm pe partie \\ Cine vrea sa se joace PACMAN \\ Voi naveti somn azi | Bcjb bstfpt fxbnfouc ef PC \\ Jo vbdbotb eprn. Eprn pf pbrtjf \\ Djof vrfb sb sf kpbdf PBDNBO \\ Vpj obvftj spno bzj | | ||