Home > Software engineering >  Huge issues assigning arrays to vectors made of structs?
Huge issues assigning arrays to vectors made of structs?

Time:03-23

So Im making a project and I litteraly tried to do the same as a friend but for some reason i keep getting the error: assignment to expression with array type, idk how to avoid.

So I have a struct called Aeroporto and a list lista_A made out of Aeroportos. I'm asking for the user to define what is going to be inside each Aeroporto and if there's nothing wrong with the input he provides then it would save the Aeroporto in the list list_A but its not working.

I ve not been able to progress for an entire day and i really could use a way out

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

#define LEN_ID 3
#define LEN_P 30
#define LEN_CIDADE 50
#define AT 40

#define STR(x) #x

#define XSTR(x) STR(x)

typedef struct aeroporto
{
    char id[LEN_ID   1];
    char pais[LEN_P   1];
    char cidade[LEN_CIDADE   1];
} Aeroporto;

int soMaiusculas(char s[])
{
    int i = 0, len = strlen(s);
    for (;i<len;i  )
    {
        if (s[i]< 'A' || s[i]>'Z')
            return 0;
    }
    return 1;
}

int main()
{   
    char input, p_id[LEN_ID ], p_pais[LEN_P ], p_cidade[LEN_CIDADE ], c;
    int i = 0; 
    Aeroporto lista_a[AT];
    
    scanf("%c",&input);

    while (input != 'q'){
        if (input == 'a')
        {
            scanf("%" XSTR(LEN_ID) "s",p_id);
            scanf("%" XSTR(LEN_P) "s",p_pais);
            scanf("%" XSTR(LEN_CIDADE) "[^\n]", p_cidade);  
            scanf("%*c");
            printf("airport %s, %s, %s\n",p_id, p_pais, p_cidade);
            if (!soMaiusculas(p_id))
                printf("invalid airport ID\n");
            else if (i==AT)
                printf("too many airports\n");
            /*else if (existeAero(lista_a, id))*/
            
            else{
                lista_a[i].id = p_id; //Now this is where the error is happening but following my //friend's advice it should work no?
                lista_a[i].pais = p_pais;
                lista_a[i].cidade = p_cidade;
                i  ;
            }
        }
        scanf("%c",&input);
    }
    return 0;```

CodePudding user response:

To reiterate the comments:

Unfortunately, your friend is incorrect here. You can not assign one array directly to another array. You must copy each element one by one.

For strings, the standard library provides the function strcpy that does this for us.

For general use cases, memcpy and memmove exist.

So

lista_a[i].id = p_id;
lista_a[i].pais = p_pais;
lista_a[i].cidade = p_cidade;

should be

strcpy(lista_a[i].id, p_id);
strcpy(lista_a[i].pais, p_pais);
strcpy(lista_a[i].cidade, p_cidade);

Also, your temporary buffers should be one byte larger:

char input, p_id[LEN_ID   1], p_pais[LEN_P   1], p_cidade[LEN_CIDADE   1];

As an aside, there are several things that can go wrong with your parsing scheme.

The return value of the *scanf family of functions returns the number of successful conversions that occurred, and should always be tested in case of parsing failure, or to check for error.

A field-width specifier (Bs) is the maximum number of characters permitted to be read. The minimum is always 1. All airport codes are exactly 3 characters in length.

Additionally, your string inputs can bleed into one another:

  • If ABCDEF is submitted as the airport ID, DEF will be the first characters read into the country buffer. Similar situation for the country and city buffers.
  • If the string submitted for the city exceeds 50 characters, the 52nd character will bleed into your control statements.

scanf offers very little in the way of recovering from bad inputs.

Consider using a line-based approach, using functions like fgets or getline and parsing with sscanf.

CodePudding user response:

This is the error-generating statement:

lista_a[i].id = p_id;

That statement assigns a pointer (p_id) to an array (lista_a[i].id). This is not a valid assignment because a pointer is not assignable to a char array and besides, the pointers generally occupy more than the 3 bytes in your array. I am guessing that you really want to copy the contents of p_id into to the id field. Since both arrays are the same length (LEN_ID), this would be a good way to do the copy:

strncpy(lista_a[i].id, p_id, LEN_ID-1);

I'm suggesting strncpy rather than strcpy because it's safer—if the p_id string does not contain a zero termination for some reason strncpy will refuse to write beyond the end of the destination. (It will, however, also not zero-terminate, so if you want to be safe from that too, you'll need to take a little extra care.)

  •  Tags:  
  • c
  • Related