Problema de estructura en C

Mi estructura se ve como sigue:

typedef struct { unsigned long attr; char fileName[128]; } entity; 

Luego trato de asignar algunos valores pero aparece un mensaje de error …

 int attribute = 100; char* fileNameDir = "blabla....etc"; entity* aEntity; aEntity->attr = attributes; aEntity->fileName = fileNameDir; 

El comstackdor me dice:

Error: # 137: la expresión debe ser un valor modificable aEntity-> fileName = fileNameDir;

¿Por qué no puedo asignar aquí este personaje al de la estructura?

Gracias

  • Estás tratando a un char[] (y un char* , FTM) como si fuera una cadena. Lo que es no es. No puedes asignar a una matriz, tendrás que copiar los valores. Además, la longitud de 128 para los nombres de archivos parece arbitraria y podría ser una fuente potencial de desbordamientos de búfer. ¿Qué hay de malo en usar std::string ? Eso te libra de todos estos problemas.
  • Está definiendo un puntero a alguna entity , no lo inicialice, y luego lo utiliza como si en la dirección aleatoria a la que apunta era un objeto de entity válido.
  • No hay necesidad de typedef una struct en C ++, ya que, a diferencia de C, en la struct C ++ los nombres viven en el mismo espacio de nombres que otros nombres.

Si absolutamente debe usar la struct como está definida en su pregunta (está predefinida), mire las otras respuestas y obtenga “El lenguaje de progtwigción C” . De lo contrario, es posible que desee utilizar este código:

 struct entity { unsigned long attr; std::string fileName; }; entity aEntity; aEntity.attr = 100; aEntity.filename = "blabla....etc"; 

No se puede asignar un puntero a una matriz. Use strncpy () para copiar la cadena:

 strncpy( aEntity->fileName, fileNameDir, 128 ); 

Esto dejará el destino sin terminación nula si la fuente es más larga que 128. Creo que la mejor solución es tener un búfer más grande por uno, copiar solo N bytes y configurar el byte N + 1 en cero:

 #define BufferLength 128 typedef struct { unsigned long attr; char fileName[BufferLength + 1]; } entity; strncpy( aEntity->FileName, fileNameDir, BufferLength ); *( aEntity->FileName + BufferLength ) = 0; 

Debería copiar la cadena de nombre de archivo, no cambiar a donde apunta.

¿Estás escribiendo C o C ++? No existe un lenguaje llamado C / C ++ y la respuesta a su pregunta varía según el idioma que esté utilizando. Si está utilizando C ++, debe usar std::string lugar de cadenas en C antiguas.

Hay un problema importante en su código que no vi en la dirección de otros carteles:

 entity* aEntity; 

declara una aEntity (debe ser una anEntity ) como un puntero a una entity pero no se inicializa. Por lo tanto, como todos los punteros sin inicializar, apunta a la basura. Por lo tanto:

 aEntity->attr = attributes; 

Invoca un comportamiento indefinido.

Ahora, dada una anEntity correctamente inicializada, anEntity->fileName es una matriz, no un puntero a una matriz de caracteres (consulte la pregunta 6.2 en la lista de Preguntas frecuentes de C). Como tal, necesita copiar sobre la cadena de caracteres apuntada por fileNameDir al bloque de memoria reservado para anEntity->fileName .

Veo muchas recomendaciones para usar strncpy . No soy partidario de pensar en strncpy como un reemplazo más seguro para strcpy porque realmente no lo es. Ver también ¿Por qué es inseguro strncpy ?

 #include  #include  #include  typedef struct st_entity { unsigned long attr; char fileName[FILENAME_MAX + 1]; } entity; int main(void) { int status = EXIT_FAILURE; unsigned long attribute = 100; char *fileNameDir = "blabla....etc"; entity *anEntity = malloc(sizeof(*anEntity)); if ( anEntity ) { anEntity->attr = attribute; anEntity->fileName[0] = '\0'; strncat(anEntity->fileName, fileNameDir, sizeof(anEntity->fileName) - 1); printf("%lu\n%s\n", anEntity->attr, anEntity->fileName); status = EXIT_SUCCESS; } else { fputs("Memory allocation failed", stderr); } return status; } 

Ver strncat .

Estás tratando de usar char * como si fuera una cadena, pero no lo es. En particular, le está diciendo al comstackdor que establezca el nombre de archivo, una matriz de caracteres de tamaño 128, a la dirección de memoria indicada por fileNameDir.

Utilice strcpy: http://cplusplus.com/reference/clibrary/cstring/strcpy/

No puede asignar un puntero a char a una matriz char, no son compatibles de esa manera, necesita copiar contenido de uno a otro, strcpy, strncpy …

Utilice strncpy ():

 strncpy( aEntity->fileName, fileNameDir, sizeof(entity.fileName) ); aEntity.fileName[ sizeof(entity.fileName) - 1 ] = 0; 

La función strncpy () es similar, excepto que no se copian más de n bytes de src. Por lo tanto, si no hay un byte nulo entre los primeros n bytes de src, el resultado no terminará en nulo. Ver la página del manual.

1) La línea char* fileNameDir = "blabla....etc" crea un puntero a char y le asigna una dirección; la dirección en este caso es la dirección del texto "blabla....etc" reside en la memoria.

2) Además, las matrices ( char fileName[128] ) no se pueden asignar en absoluto; solo se puede asignar a miembros de una matriz (por ejemplo, array[0] = blah ).

Sabiendo (1) y (2) arriba, debería ser obvio que asignar una dirección a una matriz no es algo válido por varias razones.

Lo que debe hacer en su lugar es copiar los datos a los que apunta fileNameDir , a la matriz (es decir, a los miembros de la matriz), utilizando por ejemplo strncpy .

También tenga en cuenta que simplemente ha asignado un puntero a su estructura, pero no hay memoria para guardar los datos de la estructura en sí.

En primer lugar, ¿se supone que esto es C o C ++? Los dos no son iguales o libremente intercambiables, y la respuesta “correcta” será diferente para cada uno.

Si esto es C, tenga en cuenta que no puede asignar cadenas a matrices utilizando el operador ‘=’; debe usar strcpy () o strncpy ():

 /** * In your snippet above, you're just declaring a pointer to entity but not * allocating it; is that just an oversight? */ entity *aEntity = malloc(sizeof *aEntity); ... strcpy(aEntity->fileName, fileNameDir); 

o

 strncpy(aEntity->fileName, fileNameDir, sizeof aEntity->fileName); 

con las verificaciones apropiadas para un carácter nulo de terminación.

Si esto es C ++, debería usar el tipo std :: string para en lugar de char * o char []. De esa manera, puede asignar datos de cadena utilizando el operador ‘=’:

 struct entity {unsigned long attr; std::string fileName}; entity *aEntity = new entity; std::string fileNameDir = "..."; ... entity->fileName = fileNameDir; 

El principal problema es que usted declaró un puntero a una estructura, pero no le asignó espacio (a menos que dejara un código crítico). Y los otros problemas que otros han señalado.

El problema radica en el hecho de que no se puede usar un puntero sin inicializarlo a una variable del mismo tipo de datos, que en este caso es una variable de entidad. Sin esto, el puntero apuntará a una ubicación de memoria aleatoria que contiene algunos valores de basura. Obtendrá fallos de segmentación cuando intente jugar con tales punteros.

Lo segundo que se debe tener en cuenta es que no puede asignar directamente cadenas a las variables con el operador de asignación (=). Debe usar la función strcpy () que se encuentra en el archivo de encabezado string.h.

La salida del código es: 100 blabla …… etc

 #include  #include  #include  typedef struct { unsigned long attr; char fileName[128]; } entity; void main() { unsigned long int attribute = 100; char *fileNameDir = "blabla....etc"; entity struct_entity; entity *aEntity = &struct_entity; aEntity->attr = attribute; strcpy(aEntity->fileName, fileNameDir); printf("%ld %s", struct_entity.attr, struct_entity.fileName); } 

Para char fileName [128], fileName es la matriz que tiene una longitud de 128 char. no puedes cambiar el nombre del archivo. Puede cambiar el contenido de la memoria que apunta el nombre de archivo usando strncpy (aEntity-> fileName, fileNameDir, 128);