Función C cadena de cambio utilizando puntero

Estoy tratando de hacer una función que cambie una matriz de caracteres de la función principal, eso es lo que estoy tratando de hacer:

#include  #include  #include  void change(char *a); int main() { char a[] = "hello"; printf("\na = %s", a); change(a); printf("%\na = %s", a); getch(); } void change(char *a) { a = "goodbye"; } 

Hay varios problemas con este código, pero primero debemos dar un paso atrás y hablar sobre cómo se manejan los arreglos en C.

Excepto cuando es el operando de sizeof o unary & operator, o si se utiliza un literal de cadena para inicializar otra matriz en una statement, una expresión de tipo “matriz de elementos N de T ” se convertirá (“decaer”) en una Expresión de tipo “puntero a T “, y el valor de la expresión será la dirección del primer elemento de la matriz.

En la declaracion

 char a[] = "hello"; 

"hello" es una cadena literal, que tiene el tipo “matriz de 6 elementos de char ” (5 caracteres más el terminador 0). Dado que se utiliza para inicializar la matriz a en una statement, la regla anterior no se aplica; en su lugar, el tamaño de a se establece para ser el mismo que el tamaño del literal (6), y el contenido de la cadena literal se copia en la matriz.

Cuando se llama change de main como

 change(a); 

la expresión a tiene tipo “matriz de 6 elementos de char “. Dado que no es ni una cadena literal ni el operando de sizeof o unary & operator, esa expresión se convertirá en tipo “puntero a char “, y el valor de la expresión será la dirección del primer elemento de la dirección. De ahí que la función de change sea ​​declarada como

 void change(char *a); 

En este contexto, a es simplemente un puntero. Cuando escribes

 a = "goodbye"; 

la cadena literal "goodbye" no se usa en un inicializador, y no es el operando de sizeof o unary & operator, por lo que la expresión se convierte al tipo “puntero a char “, y el valor de la expresión es la dirección de el primer personaje Entonces, lo que sucede aquí es que estás copiando la dirección de la cadena literal "goodbye" a a . Esto sobrescribe el valor en a , pero este a no es el mismo objeto en la memoria que la matriz en main , por lo que cualquier cambio en él no se refleja en main .

Si desea actualizar el contenido de una matriz, deberá usar las funciones de biblioteca strcpy/strncpy (para cadenas terminadas en 0) o memcpy (para todo lo demás), o actualizar cada elemento explícitamente ( a[0]='g'; a[1]='o'; a[2]='o'; , etc).

Para actualizar los contenidos de a , usarías

 strcpy( a, "goodbye" ); 

Excepto

a es solo lo suficientemente grande para contener 5 caracteres más un terminador 0; "goodbye" es de 7 caracteres más el terminador 0; es dos caracteres más grandes de lo que a es capaz de almacenar. La tecnología C le permitirá realizar la operación y eliminar los bytes inmediatamente después de a , lo que puede ocasionar muchos problemas (la saturación del búfer, como este, es un exploit de malware clásico). Tienes un par de opciones en este momento:

Primero, puedes declarar que a tamaño sea lo suficientemente grande como para manejar cualquiera de las cadenas:

 #define MAX_LEN 10 ... char a[MAX_LEN] = "hello"; 

En segundo lugar, podría limitar el tamaño de la cadena copiada a:

 void change( char *a, size_t size ) { strncpy( a, "goodbye", size - 1 ); a[size - 1] = 0; } 

Tenga en cuenta que necesitará pasar la cantidad de elementos que a almacén puede almacenar como un parámetro separado cuando llame al change ; No hay forma de saber a partir de un puntero qué tan grande es el arreglo al que apunta:

 change( a, sizeof a / sizeof *a ); // although in this case, sizeof a would be // sufficient. 

El principal problema es el envío de una copia del punto de referencia de char haciendo esto:

 void change(char *a) { a = "goodbye"; } 

Si desea cambiar un valor en otra función, debe hacer esto:

 #include  #include  #include  void change(char **a); int main() { char *a = "hello"; printf("\na = %s", a); change(&a); printf("%\na = %s", a); getch(); } void change(char **a) { *a = "goodbye"; } 

Cambié la función, ahora funciona, de esta manera:

 void change(char *a) { strcpy(a, "goodbye"); }