2010-03-13 23 views
6

¿por qué se bloquea este código? está usando strcat ilegal en punteros de caracteres?¿por qué se bloquea este código?

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

int main() 
{ 
    char *s1 = "Hello, "; 
    char *s2 = "world!"; 
    char *s3 = strcat(s1, s2); 
    printf("%s",s3); 
    return 0; 
} 

por favor, deténgase de una manera adecuada al referirse tanto a la matriz como a los punteros.

+2

está utilizando mal strcat. Añade la segunda cadena al final de la primera cadena. La cadena que devuelve es solo una conveniencia. No puede alterar una cadena constante (su s1), es por eso que se bloquea. s1 apunta a la memoria de solo lectura. –

+14

Si todo estaba perfectamente bien, el código no se bloqueará. –

+1

Es posible que desee editar su pregunta, Ashish. Probablemente recibas votos negativos porque dices "aunque todo está perfectamente bien". Sin embargo, es una pregunta muy válida. –

Respuesta

11

El problema es que s1 apunta a un literal de cadena y está intentando modificarlo añadiéndole s2. No tiene permitido modificar literales de cadena. Es necesario crear una matriz de caracteres y copiar las dos cadenas en ella, así:

char *s1 = "Hello, "; 
char *s2 = "world!"; 

char s3[100] = ""; /* note that it must be large enough! */ 
strcat(s3, s1); 
strcat(s3, s2); 
printf("%s", s3); 

"suficientemente grande" significa que al menos strlen(s1) + strlen(s2) + 1. El + 1 es para dar cuenta del terminador nulo.

Dicho esto, usted debe considerar seriamente el uso strncat (o el strlcat sin duda mejor, pero no estándar, si está disponible), que son los límites-controladas, y por lo tanto son muy superiores a strcat.

+0

¡Matrices de longitud variable (c99) o cualquier cantidad inferior a 100! : P –

+0

La razón por la cual 'strcat' devuelve su primer argumento es una conveniencia para situaciones como esta - significa que puede hacer la concatenación en una línea:' strcat (strcat (s3, s1), s2); ' – caf

+0

I De hecho prefiero snprintf a strncat en casi todos los casos como este. Es un golpe de rendimiento menor, pero es más probable que se use correctamente, ya que el uso correcto de strncat no es coherente con el resto de la biblioteca. (La 'n' significa algo diferente de lo que parece pensar la gente.) –

2

La forma correcta en este caso sería asignar suficiente espacio en la cadena de destino (s1) para almacenar 6 caracteres adicionales (s2), así como el terminador nulo para la cadena.

char s1[14] = "Hello, "; 
char *s2 = "world!"; 
char *s3 = strcat(s1, s2); 
printf("%s",s3); 
0

Aquí es una cita del manual de strcat(): "La función strcat() añade la cadena src a la cadena dest, sobrescribiendo el byte nulo ('\ 0') al final de dest, y luego agrega un byte nulo de terminación. Las cadenas no se pueden superponer, y la cadena de dest debe tener suficiente espacio para el resultado ".

El problema aquí es que s1 y s2 apuntan a cadenas estáticas que son "de solo lectura", por lo que si intentas realizar una operación strcat, con una cadena de este tipo en los parámetros, obtendrás un error.

La mejor manera de crear su cadena de hello world aquí es malloc, por lo que podrá contener tanto s1 como s2. Además, no se olvide de agregar una '\ n' al final de su cadena de formato de impresión, de lo contrario, podría sorprenderse.

Aquí está el código que escribiría si fuera tú:


int main() 
{ 
    char* s1 = "Hello "; 
    char* s2 = "World !"; 
    char *s3 = malloc((strlen(s1) + strlen(s2) + 1) * sizeof(char)); 
/* +1 is for the null terminating character 
and sizeof(*s3) is the actual size of a char. */ 

    if (s3) 
    { 
    strcat(s3, s1); 
    strcat(s3, s2); 
    printf("%s\n", s3); 
    free(s3); // always free what you alloc when you don't need it anymore. 
    } 
    return 0; 
} 
Cuestiones relacionadas