Reputation: 17
I'm trying to write a program that will create a database made of entries (reg), the amount of which is set by the user at runtime.
My idea was to make a type struct
dynamic array to store my entries but I'm having a hard time storing the values in the array, I've tried direct assignment but that didn't work, as soon as I type in the first value the program crashes, I looked into it and most people seem to use a dedicated function to insert elements into the array, but I'm having a hard time understanding how to go about it.
typedef struct
{
char nome[60];
char morada[60];
char codigop[60];
char telefone[20];
char aniver[20];
char sexo;
char prof[60];
float altura;
long contribuinte;
} reg;
// array of structs
typedef struct
{
reg *array;
size_t used;
size_t size;
} Array;
//crashes
void Populador(int tamanho, reg * a){
char nomed[60];
for (int i = 0; i < tamanho; i ++){
printf("Quais os dados do %d registo? \n ", i+1);
printf("Lembrete, a ordem e: nome, morada, codigo postal, telefone, "
"data de nascimento, genero, profissao, altura, contribuinte. \n");
scanf(" %s", &a[i].nome);
scanf(" %s", a[i].morada);
scanf(" %s", a[i].codigop);
scanf(" %s", a[i].telefone);
scanf(" %s", a[i].aniver);
scanf(" %c", a[i].sexo);
scanf(" %s", a[i].prof);
scanf(" %f", a[i].altura);
scanf(" %long", a[i].contribuinte);
}
}
int main() {
int option;
char key[60], read[20], write[20];
int tamanho; //size
char number[20];
Array a = { 0 };
printf( "1 - Criar um nova base de dados com dimensão especificada pelo utilizador\n" //create new data base
"2 - Guardar a base de dados existente num ficheiro de texto\n"
"3 - Carregar uma base de dados a partir de um ficheiro gravado previamente\n"
"4 - Listar toda a informacao da base de dados no ecra\n"
"5 - Consultar um contacto a partir do seu numero \n"
"6 – Procurar um contacto a partir do nrº de contribuinte \n"
"7 - Listar todos os contactos cujo nome contém um nome/palavra inserido pelo utilizador \n"
"8 – Ordenar os contactos por ordem alfabetica de nome\n"
"9 - Modificar dados de um registo \n"
"10 - Sair do programa \n ");
do {
scanf(" %d", &option);
switch (option) {
case 1:
scanf( " %d", &tamanho);
Populador(tamanho, &a);
break;
case 2:
printf( "Qual o nome do ficheiro? /n");
scanf(" %s", &read[20]);
readf(read);
break;
case 3:
printf( "Qual o nome do ficheiro no qual quer guardar a base de dados?\n");
scanf( " %s" ,&write[20]);
writef(write);
break;
case 4:
display(tamanho, &a);
//chamar funcao display
break;
case 5:
scanf(" %d", &number);
if( (number <= tamanho) ) {
search(number, &a);
}
break;
case 6:
if (searchcont(tamanho, &a) == 1){
printf("O contribuinte que procurou foi encontrado no indice %d \n", (searchcont(tamanho, &a)));
}
else
printf("O contribuinte que procurou nao foi encontrado na base de dados \n");
break;
case 7:
searchkey(tamanho, &a, key);
break;
case 8:
bubble_sort(tamanho, &a);
//ordenar por ordem alfabetica
break;
case 9:
change(&a);
break;
case 10:
return 1;
default:
printf( "Opcao invalida\n") ;
break;
}
}while(option != 10);
return 0;
}
Upvotes: 1
Views: 69
Reputation: 144550
Here is a small program to read and add entries to the database:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char nome[60];
char morada[60];
char codigop[60];
char telefone[20];
char aniver[20];
char sexo;
char prof[60];
float altura;
long contribuinte;
} reg;
// array of structs
typedef struct {
reg *array;
size_t used;
size_t size;
} Array;
int add_entry(Array *data, const reg *e) {
if (data->used == data->size) {
size_t new_size = data->size + data->size / 2 + 16;
reg *new_array = realloc(data->array, sizeof(*new_array) * new_size);
if (new_array == NULL) {
// failure: return error
return -1;
}
data->size = new_size;
data->array = new_array;
}
memcpy(&data->array[data->used++], e, sizeof(*e));
return 0;
}
void free_entries(Array *a) {
free(a->array);
a->array = NULL;
a->used = a->size = 0;
}
int Populador(int tamanho, Array *a) {
reg e;
int i = 0;
while (i < tamanho) {
printf("Quais os dados do %d registo?\n ", i+1);
printf("Lembrete, a ordem e: nome, morada, codigo postal, telefone, "
"data de nascimento, genero, profissao, altura, contribuinte.\n");
if (scanf("%59s %59s %59s %19s %19s %c %59s %f %ld",
e.nome, e.morada, e.codigop, e.telefone, e.aniver, &e.sexo,
e.prof, &e.altura, &e.contribuinte) != 9) {
int c;
printf("invalid input\n");
while ((c = getchar()) != EOF && c != '\n')
continue;
if (c == EOF)
break;
continue;
}
if (add_entry(a, &e)) {
break;
}
i++;
}
return i;
}
int main() {
Array a = { 0 };
int n = Populador(10, &a);
printf("%d entries\n", n);
free_entries(&a);
return 0;
}
Upvotes: 2
Reputation: 67476
IMO better way :
typedef struct
{
char nome[60];
char morada[60];
char codigop[60];
char telefone[20];
char aniver[20];
char sexo;
char prof[60];
float altura;
long contribuinte;
} reg;
// array of structs
typedef struct
{
size_t used;
size_t size;
reg data[];
} Array;
Array *allocate(Array *arr, size_t newsize)
{
Array *newarray = realloc(arr, sizeof(*newarray) + newsize * sizeof(newarray -> data[0]));
if(newarray)
{
if(arr) newarray -> used = arr -> used;
newarray -> size = newsize;
}
return newarray;
}
only one allocation needed.
Upvotes: 2