funcion - ¿Por qué primero tengo que strcpy() antes de strcat()?
union de cadenas en c (5)
Además, no recomendaría el uso de strcpy
o strcat
ya que pueden conducir a algunos problemas no deseados.
Use strncpy
y strncat
, ya que ayudan a prevenir los desbordamientos de búfer.
¿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");
En el primer caso, las stuff
contienen basura. strcat
requiere que tanto el destino como la fuente contengan cadenas terminadas en nulo adecuadas.
strcat(stuff, "hi ");
escaneará las stuff
busca de un carácter ''/0''
terminación, donde comenzará a copiar "hi "
. Si no lo encuentra, se ejecutará desde el final de la matriz, y pueden suceder 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 puedes inicializar stuff
a una cadena vacía:
char stuff[100] = "";
que llenará todos los 100 bytes de stuff
con ceros (la claridad aumentada probablemente vale la pena en cualquier problema menor de rendimiento).
Porque las stuff
no están inicializadas antes de la llamada a strcpy
. Después de que la declaración no sea una cadena vacía, se trata de datos sin inicializar.
strcat
agrega datos al final de una cadena, es decir, encuentra el terminador nulo en la cadena y agrega caracteres después de eso. Una cadena no inicializada no se garantiza que tenga un terminador nulo, por lo que es probable que strcat
se bloquee.
Si tuviera que inicializar las stuff
como se muestra a continuación, podría realizar el strcat:
char stuff[100] = "";
strcat(stuff,"hi ");
strcat(stuff,"there");
Strcat añade una cadena a la 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 se inicialice dest
para corregir los valores de cadena de c. Puede tener suerte de tener una matriz con el primer valor de cero en char stuff[100];
, pero no debes confiar en ello.
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án inicializadas, por lo que podría comenzar con NUL, o podría no tener NUL en ningún lugar dentro de él.
En C ++, puedes hacer esto:
char stuff[100] = {}; // ''stuff'' is initialized to all zeroes
Ahora puede hacer strcat, porque el primer carácter de ''stuff'' es el terminador nulo, por lo que se agregará al lugar correcto.
En C, aún necesitas inicializar ''cosas'', que se pueden hacer de dos 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.