¿Por qué primero tengo que hacer strcpy() antes que strcat()?

4 minutos de lectura

avatar de usuario
o Cyngiser

¿Por qué este código produce problemas de tiempo de ejecución?

char stuff[100];
strcat(stuff,"hi ");
strcat(stuff,"there");

pero esto no?

char stuff[100];
strcpy(stuff,"hi ");
strcat(stuff,"there");

strcat buscará el terminador nulo, lo interpretará como el final de la cadena y agregará el nuevo texto allí, sobrescribiendo el terminador nulo en el proceso y escribiendo un nuevo terminador nulo al final de la concatenación.

char stuff[100];  // 'stuff' is uninitialized

¿Dónde está el terminador nulo? stuff no está inicializado, por lo que podría comenzar con NUL, o podría no tener NUL en ninguna parte.

En C++, puedes hacer esto:

char stuff[100] = {};  // 'stuff' is initialized to all zeroes

Ahora puede hacer strcat, porque el primer carácter de ‘cosas’ es el terminador nulo, por lo que se agregará en el lugar correcto.

En C, aún necesita inicializar ‘cosas’, lo que se puede hacer de varias maneras:

char stuff[100]; // not initialized
stuff[0] = '\0'; // first character is now the null terminator,
                 // so 'stuff' is effectively ""
strcpy(stuff, "hi ");  // this initializes 'stuff' if it's not already.

  • {} no es un inicializador válido en C.

    –Keith Thompson

    16/09/2013 a las 23:25

  • ¡Bah! me perdí el C etiqueta. Gracias.

    – Tim

    16/09/2013 a las 23:26

  • deberías poder hacer char stuff[100] = {0}; aunque.

    – Zan Lince

    17 de septiembre de 2013 a las 0:05

  • preferiría char stuff[100]=""; para la inicialización, aunque la mayoría de los casos la primera asignación es una estrellita.

    – Rufus VS

    14/09/2018 a las 20:11


En el primer caso, stuff contiene basura. strcat requiere que tanto el destino como el origen contengan cadenas adecuadas terminadas en nulo.

strcat(stuff, "hi ");

escaneará stuff para una terminación '\0' carácter, donde comenzará a copiar "hi ". Si no lo encuentra, se ejecutará al final de la matriz y pueden ocurrir cosas arbitrariamente malas (es decir, el comportamiento no está definido).

Una forma de evitar el problema es así:

char stuff[100];
stuff[0] = '\0';      /* ensures stuff contains a valid string */
strcat(stuff, "hi ");
strcat(stuff, "there");

O puede inicializar stuff a una cadena vacía:

char stuff[100] = "";

que llenará los 100 bytes de stuff con ceros (la mayor claridad probablemente valga cualquier problema menor de rendimiento).

avatar de usuario
shf301

Porque stuff no está inicializado antes de la llamada a strcpy. Después de la declaración stuff no es una cadena vacía, son datos no inicializados.

strcat agrega datos al final de una cadena, es decir, encuentra el terminador nulo en la cadena y agrega caracteres después de eso. No se garantiza que una cadena no inicializada tenga un terminador nulo, por lo que strcat es probable que se bloquee.

Si hubiera que inicializar stuff como se muestra a continuación, puede realizar los strcat:

char stuff[100] = "";
strcat(stuff,"hi ");
strcat(stuff,"there");

  • La respuesta está completa, pero en el caso de que un principiante no entienda: la primera línea agregó la inicialización con una cadena vacía (sin caracteres), pero como cualquier cadena entre comillas dobles, tiene un carácter de terminación nulo (generalmente 0x00) en el final. Ese es el carácter, que el strcat está buscando. En otras palabras, la inicialización hizo esto: stuff[0] = 0;

    – EmbeddedGuy

    19 sep 2021 a las 8:41

Strcat agrega una cadena a una cadena existente. Si la matriz de cadenas está vacía, no irá a buscar el final de la cadena ('\0') y causará un error de tiempo de ejecución.

De acuerdo con la página de manual de Linux, strcat simple se implementa de esta manera:

   char*
   strncat(char *dest, const char *src, size_t n)
   {
       size_t dest_len = strlen(dest);
       size_t i;

       for (i = 0 ; i < n && src[i] != '\0' ; i++)
           dest[dest_len + i] = src[i];
       dest[dest_len + i] = '\0';

       return dest;
   }

Como puede ver en esta implementación, strlen(dest) no devolverá la longitud de cadena correcta a menos que dest se inicializa para corregir los valores de cadena c. Puede tener suerte si tiene una matriz con el primer valor de cero en char stuff[100]; pero no debes confiar en ello.

avatar de usuario
Marcos José Jorgensen

Además, recomendaría no usar strcpy o strcat ya que pueden conducir a algunos problemas no deseados.

Utilizar strncpy y strncatya que ayudan a prevenir desbordamientos de búfer.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad