Laborator 10: Operații cu tablouri, structuri și alocare dinamică de memorie

Obiectivele laboratorului

În acest laborator vom studia:

Acest laborator nu are pagină nouă de teorie, însă necesită recapitularea noțiunilor indicate.

Exerciții

ATENȚIE: Toate exercițiile vor fi verificate și cu valgrind. Toate sarcinile se vor realiza folosind o abordare modularizată (cu funcții). Discutați cu asistentul alegerile voastre, dacă nu sunteți siguri care ar trebui să fie semnăturile funcțiilor.

  1. Fie definiția de mai jos a unei structuri:
// maxim 30 de caractere printabile + '\0'
#define NAME_LEN 31

struct __attribute__((__packed__)) person {
	char name[NAME_LEN];
	int age;
};
// sau
typedef struct __attribute__((__packed__)) {
	char name[NAME_LEN];
	int age;
} person_t;

a. Scrieți un program care citește membrii unei astfel de structuri și face scrierea ei într-un fișier binar (1-gigel.bin). Reprezentarea în fișier a informației trebuie să aibă sizeof(struct person) (sizeof(person_t)), iar - prin convenție, toți octeții nefolosiți ai structurii (rezultați, de exemplu, prin citirea unui nume mai scurt de 30 de caractere), trebuie să fie inițializați la zero.

Important! În codul programului vostru trebuie să aveți exact un apel al funcției fwrite (nu mai multe).

Exemplu:

Se vor citi următoarele date de la stdin:

Gigel 25

Se va genera fișierul 1-gigel.bin având următorul conținut:

$ hexdump -C 1-gigel.bin
00000000  47 69 67 65 6c 00 00 00  00 00 00 00 00 00 00 00  |Gigel...........|
00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 19  |................|
00000020  00 00 00                                          |...|
00000023

// putem inspecta si dimensiunea fișierul: 35 bytes (0x23)
// 35 = 31 (NAME_LEN bytes pentru name) + 4 (19 00 00 00 == 25)
$ ls -l gigel.bin     
-rw-r--r--  1 dorinel  wheel  35 Nov 26 00:33 1-gigel.bin

b. Scrieți un program care citește structura din fișierul general anterior și afișează, pe ecran, numele și vârsta persoanei.

Important! În codul programului vostru trebuie să aveți exact un apel al funcției fread (nu mai multe).

  1. Fie varianta alternativă a structurii:
struct person {
	char *name;
	int age;
};

// sau

typedef struct {
	char *name;
	int age;
} person_t;
// Obs. name are lungime variabilă și se alocată dinamic

a. Refaceți exercițiul 1.a. considerând folosirea câmpului nume alocat dinamic. Noul fișier se va numi 2-gigel.bin.

Restricția de a folosi un singur apel de fwrite nu se mai păstrează.

De data aceasta folosiți convenția de la laboratorul trecut (de a preceda câmpul nume de lungimea lui în octeți, sub forma unui int) și asigurați-vă că structura ocupă exact același număr de octeți ca cea din exemplul următor.

Exemplu:

Se vor citi următoarele date de la stdin:

Gigel 25

Se va genera fișierul 2-gigel.bin având următorul conținut:

$ hexdump -C 2-gigel.bin 
00000000  06 00 00 00 47 69 67 65  6c 00 19 00 00 00        |....Gigel.....|
0000000e

// putem inspecta si dimensiunea fișierul: 14 bytes (0x0e)
// 14 = 4 (06 00 00 00 == lungime in bytes) + 6 ("Gigel\0") + 4 (19 00 00 00 == 25)
$ ls -l 2-gigel.bin
-rw-r--r--  1 dorinel  wheel  14 Nov 26 00:48 gigel2.bin

b. Scrieți un program care citește structura creată la punctul anterior și afișează informațiile persoanei pe ecran.

Restricția de a folosi un singur apel de fread nu se mai păstrează.

Mențiune! Afișarea câmpurilor se va face obligatoriu, prin utilizarea structurii, după crearea unei variabile de acel tip.

  1. Creați un program care citește de la tastatură un număr natural n, apoi scrie n structuri, de tipul celor din exercițiul 2, cu date citite de la stdin într-un fișier binar 3-gigel.bin. Formatul de reprezentare a array-ului trebuie să eficient.

Verificați corectitudinea modului de reprezentare prin crearea unui program care citește cele n structuri din fișier și afișează detaliile persoanelor din acele structuri.

Mențiune! Afișarea structurilor se va face obligatoriu, prin utilizarea structurii, după citirea întregului array în memorie.

Pentru o aprofundare mai bună a conceptelor prezentate în laborator, vă recomandăm să parcurgeți materialele din arhivele demo_parsing.zip și demo_struct_binary_files.zip de pe Moodle.