W *alloc(...) nie jest potrzebne rzutowanie w języku C. *alloc(...) zwraca typ void * który w standardzie konwertuje się automatycznie do typu docelowego. Z kolei w C++ konsekwencje użycia *alloc(...) są tak drastyczne że bywa wręcz w kodzie C++ zabroniony. Ale tylko w C++, reguły języka nakazują rzutować.
memset(...) także jest zbędny. Wystarczy (od C90) przypisanie {0} w trakcie inicjalizacji do tablicy lub nieco asekuranckie calloc(...) dla wcześniejszych standardów.
W tym kodzie brakuje:
1. Alokacji tablicy na podaną ilość osób.
2. Poprawnego obsłużenia błędów.
3. Trochę niezręczne jest obsługiwanie indeksów poprzez adresy ale zapewne "kazali".
4. Wycieki pamięci...
5. Z racji tego że nie ma wydzielonych funkcji (a IMHO powinny być), prawidłowa obsługa błędów alokacji będzie wymagała idiomu z goto który bywa źródłem zażartych dyskusji aczkolwiek jest szeroko używany.
6. No i nazewnictwo. O ile i czy j to "zwyczajowe nazwy", to nazywanie danych osoby data, to pomyłka.
7. scanf(...) także bym nie używał bo to funkcja niebezpieczna ale tu już nie zmieniałem (w konsekwencji program ma potencjalną podatność :-/ )
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
struct person {
int id;
char name[50];
char lastName[50];
};
extern int errno;
int main(void)
{
size_t persons_counter;
struct person * persons_table;
size_t count_written;
size_t i;
FILE *fp;
fp = fopen("plik.txt", "w");
if (fp == NULL)
{
fprintf(stderr, "Błąd operacji na pliku plik.txt: %s.\n", strerror(errno));
goto exit_fail;
}
printf("Podaj liczbe osob: ");
scanf("%zd", &persons_counter);
persons_table = calloc(sizeof(struct person), persons_counter);
if (persons_table == NULL) {
fprintf(stderr, "Błąd alokacji tablicy: %s.\n", strerror(errno));
goto exit_1;
}
for(i = 0; i < persons_counter; ++i)
{
printf("Podaj id, imie, nazwisko: ");
scanf("%d %s %s",
&(persons_table + i)->id,
(char *)&(persons_table + i)->name,
(char *)&(persons_table + i)->lastName);
}
for(i = 0; i < persons_counter; ++i)
{
printf("Id, imie, nazwisko: %d %s %s\n",
(persons_table + i)->id,
(persons_table + i)->name,
(persons_table + i)->lastName);
}
count_written = fwrite(persons_table, sizeof(struct person), persons_counter, fp);
if(count_written != 0) {
printf("Zapisano !\n");
} else {
fprintf(stderr, "Błąd zapisu: %s\n", strerror(errno));
}
free(persons_table);
fclose (fp);
return EXIT_SUCCESS;
exit_1:
fclose(fp);
exit_fail:
return EXIT_FAILURE;
}