0

I am a beginner in C and I am trying to copy a string inside another one. I have the following code:

#include <stdio.h>
#include <string.h>

typedef struct {
    float mort_2009, mort_2015, indices;
    char estado[];
} Mortalidade;

void defineEstados (
    Mortalidade *e, 
    char estado[],
    float mort_2009,
    float mort_2015,
    int posix)
{
    strcpy(e[posix].estado, estado);
    e[posix].mort_2009 = mort_2009;
    e[posix].mort_2015 = mort_2015;
    e[posix].indice = mort_2009 / mort_2015;
}

void imprimeEstados (Mortalidade *e){
    for (int i = 0; i < 3; i++){
        printf("Estado: %s, Morte em 2009: %.1f, Morte em 2015: %.1f, Indice: %.2f \n",
            e[i].estado,
            e[i].mort_2009,
            e[i].mort_2015,
            e[i].indice);
    }
}

int main() {

    Mortalidade estados[27];

    defineEstados(estados, "AC", 12.6, 10.6, 0);
    defineEstados(estados, "AL", 12.6, 10.6, 1);
    defineEstados(estados, "AP", 12.6, 10.6, 2);
    
    imprimeEstados(estados);
    return 0;
}

My struct Mortalidade has a field called estado, which will receive a string (and other data) in the void function defineEstados. Therefore, after copying the string inside the struct using strcpy, in the void function imprimeEstados, when I want to print the estados inside my struct, the result seems like garbage inside the variable, and I don't know how to find the error. Here is the output obtained:

Estado: ��IA��)A�&�?��IA��)A�&�?AP, Morte em 2009: 12.6, Morte em 2015: 10.6, Indice: 1.19 
Estado: ��IA��)A�&�?AP, Morte em 2009: 12.6, Morte em 2015: 10.6, Indice: 1.19 
Estado: AP, Morte em 2009: 12.6, Morte em 2015: 10.6, Indice: 1.19  

Speaking personally seems like garbage concatenated, but I don't know how to fix it.

Note: I pretend to insert more estados, but I prefer to fix the code previously.

  • how many chars can you store in estado? How big is it? – stark Mar 26 '23 at 20:08
  • The `Mortalidade` type has a flexible array member. It only makes sense to have an array of *pointers* to the `struct` instances that have been allocated with sufficient memory. Having an array of `struct` will only work if its array member `estado` is a pointer, and *that* is allocated sufficient memory. – Weather Vane Mar 26 '23 at 20:09

2 Answers2

1

The problem is that you declared a structure with a flexible array member named estado

typedef struct {
    float mort_2009, mort_2015, indices;
    char estado[];
} Mortalidade

It has an incomplete character array type.

You need either to allocate memory for the data member along with an object of the structure type or to specify a fixed size of the array or declare the data member as a pointer of the type char * and allocate memory for a stored string.

The simplest way is just tp declare the data member estado like

    char estado[3];

It is enough to store your string literals.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • I tried to make char estado[2], but it did not work as well... – Guilherme Hepfener Mar 26 '23 at 20:10
  • @GuilhermeHepfener String literals like this "AC" have the type char[3]. So you need to declare the array as having the type at least char[3] if you want to use the function strcpy to copy the whole string literal in a character array. – Vlad from Moscow Mar 26 '23 at 20:12
  • @GuilhermeHepfener To be more specific, count the number of characters (letters) in your string first, add 1 to it and then use it as the `char[]` array size. For example, `"ABC"` would be a `char[4]`. – Ar Rakin Mar 26 '23 at 20:15
  • It has complete character array type. This type is called flexible array member and if has well defined length of 0 – 0___________ Mar 26 '23 at 20:15
  • 1
    @0___________ It is a declaration of incomplete array type.:) From the C Standard "18 As a special case, the last element of a structure with more than one named member may have an incomplete array type; this is called a flexible array member" If you do not specify the number of elements in an array declaration that does not have an initializer then the array has incomplete type. – Vlad from Moscow Mar 26 '23 at 20:17
1
typedef struct {
    float mort_2009, mort_2015, indices;
    char estado[];
} Mortalidade;

estado is a flexible array member having length zero (0). You cant use this struct the way you use it in your program as static allocation will not allocate any memory for it.

This kind of struct is intended to be used with dynamic allocation.

typedef struct {
    float mort_2009, mort_2015, indices;
    char estado[];
} Mortalidade;

void defineEstados (
    Mortalidade **e, 
    char estado[],
    float mort_2009,
    float mort_2015,
    int posix)
{
    e[posix] = malloc(sizeof(**e) + strlen(estado) + 1);
    if(e[posix])
    {
        strcpy(e[posix] -> estado, estado);
        e[posix] -> mort_2009 = mort_2009;
        e[posix] -> mort_2015 = mort_2015;
        e[posix] -> indices = mort_2009 / mort_2015;
    }
}

void imprimeEstados (Mortalidade **e){
    for (int i = 0; i < 3; i++){
        if(e[i]) printf("Estado: %s, Morte em 2009: %.1f, Morte em 2015: %.1f, Indice: %.2f \n",
            e[i] -> estado,
            e[i] -> mort_2009,
            e[i] -> mort_2015,
            e[i] -> indices);
    }
}

int main() {

    Mortalidade *estados[27];

    defineEstados(estados, "AC", 12.6, 10.6, 0);
    defineEstados(estados, "AL", 12.6, 10.6, 1);
    defineEstados(estados, "AP", 12.6, 10.6, 2);
    
    imprimeEstados(estados);
    //free memory
    return 0;
}

https://godbolt.org/z/13j31hGeG

0___________
  • 60,014
  • 4
  • 34
  • 74