1

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;
}
1
  • Sorry, added the code that crashes the program. Commented Jan 30, 2021 at 23:35

2 Answers 2

2

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;
}
Sign up to request clarification or add additional context in comments.

10 Comments

What's p? Did you mean sizeof(*e)?
@DanielWalker: p should have been new_array, sizeof(*e) is the same as sizeof(reg) but I prefer to use the type of the object pointed to by e instead of the type to avoid a potential type mismatch.
Hey! First of all thanks for the comment, but when I ran it again with these changes the same thing happened, it printed this line " printf("Lembrete, a ordem e: nome, morada, codigo postal, telefone, " "data de nascimento, genero, profissao, altura, contribuinte.\n");" I typed in a name and it crashed, strange.
@ChuckNorris: did you use the above code or copy part of it? Try and compile a debug build and use the debugger to see where it crashes.
@DanielWalker So I just oppened up a new file to test out your code and it works perfectly, but when I copy it over to my project it crashes.... I have a switch with a menu in place that calls the Populador function, do you think that might be it? I can't say I know how to work with the debugger
|
2

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.