Un'alternativa è utilizzare una struttura dati che si faccia carico del lavoro al posto tuo. Per questo scopo di solito si utilizza un tipo di struttura dati chiamato vector o resizeable array. In C non sono così comodi perché normalmente costringono a utilizzare metodi per inserimento e lookup. Un trick che puoi usare per simulare un normale array è basato sui puntatori, se vuoi un esempio eccone uno qui sotto
codice:
#include <stdlib.h>#include <stdio.h>
#include <stdbool.h>
#include <string.h>
typedef struct Prodotto {
char *id_prodotto;
char *nome;
float *prezzo;
} Prodotto;
void clean_input_buffer(void) {
while (getchar() != '\n');
}
#define INITSIZE 4
#define EXPANDFACTOR 2
#define CONTRACTRATIO 0.25
#define TYPE Prodotto
typedef TYPE *vector;
static vector box(int *p) {
return (vector)(p + 2);
}
static int *unbox(vector p) {
return (((int *)p) - 2);
}
vector new_vector_init(int length){
int size = INITSIZE;
while (size < length) size *= EXPANDFACTOR;
int *ret = (int *)malloc(sizeof(TYPE)*(size)+sizeof(int) * 2);
ret[0] = size;
ret[1] = length;
return box(ret);
}
#define new_vector() new_vector_init(0)
void resize(vector *v, int length) {
int *ret = unbox(*v);
ret[1] = length;
int size = ret[0];
while (length != 0 && length / (double)size < CONTRACTRATIO) size /= EXPANDFACTOR;
while (size < length) size *= EXPANDFACTOR;
if (size != ret[0]) {
ret = (int *)realloc(ret, sizeof(TYPE)*(size)+sizeof(int) * 2);
*v = box(ret);
}
}
int length(vector v) {
return *(((int *)v) - 1);
}
int size(vector v) {
return *(((int *)v) - 2);
}
void push(vector *v, TYPE e) {
int len = length(*v);
resize(v, len + 1);
(*v)[len] = e;
}
void free_vector(vector v) {
free(unbox(v));
}
TYPE pop(vector *v) {
int len = length(*v) - 1;
TYPE ret = (*v)[len];
resize(v, len);
return ret;
}
#define MAXN 20
vector inserimento();
vector inserimentoN();
void stampa(vector p);
int main(void) {
stampa(inserimento());
puts("\n");
stampa(inserimentoN());
printf("Premi invio per terminare");
getchar();
return 0;
}
vector inserimento() {
vector ret = new_vector();
int i = 0;
char buffer[MAXN];
float b;
while (true) {
printf("\nHai inserito %d prodotti, vuoi inserirne un altro? (s/n): ", i);
char answer;
do {
answer = getchar();
} while (answer != 'n' && answer != 's');
clean_input_buffer();
if (answer == 'n') break;
Prodotto p;
printf("\nId prodotto: ");
scanf("%s", buffer);
p.id_prodotto = (char *)malloc((strlen(buffer) + 1)*sizeof(char));
strcpy(p.id_prodotto, buffer);
printf("Nome: ");
scanf("%s", buffer);
p.nome = (char *)malloc((strlen(buffer) + 1) * sizeof(char));
strcpy(p.nome, buffer);
printf("Prezzo: ");
scanf("%f", &b);
p.prezzo = (float *)malloc(sizeof(float));
*p.prezzo = b;
push(&ret, p);
i++;
}
return ret;
}
vector inserimentoN() {
int nprodotti;
puts("Quanti prodotti vuoi inserire?");
scanf("%d", &nprodotti);
vector ret = new_vector_init(nprodotti);
int i = 0;
char buffer[MAXN];
float b;
while (i < nprodotti) {
printf("\nInserisci il prodotto %d:", i);
printf("\nId prodotto: ");
scanf("%s", buffer);
ret[i].id_prodotto = (char *)malloc((strlen(buffer) + 1) * sizeof(char));
strcpy(ret[i].id_prodotto, buffer);
printf("Nome: ");
scanf("%s", buffer);
ret[i].nome = (char *)malloc((strlen(buffer) + 1) * sizeof(char));
strcpy(ret[i].nome, buffer);
printf("Prezzo: ");
scanf("%f", &b);
ret[i].prezzo = (float *)malloc(sizeof(float));
*ret[i].prezzo = b;
i++;
}
clean_input_buffer();
return ret;
}
void stampa(vector p) {
int len = length(p);
int i = 0;
while (i<len) {
printf("Id_prodotto: %s\n", p[i].id_prodotto);
printf("Nome: %s\n", p[i].nome);
printf("Prezzo: %f \n", *p[i].prezzo);
i++;
}
}
Altrimenti il metodo più convenzionale è usare una struttura con 3 campi: lunghezza, dimensione e il puntatore a memoria e manipolare il contenuto attraverso dei metodi.
Se hai accesso alla libreria C++ la soluzione ovvia è usare il template vector