strncat, strncat_s
De es.cppreference.net
| Definido en el encabezado <string.h>
|
||
char* strncat( char* dest, const char* src, size_t count );
|
(1) | (hasta C99) |
char* strncat( char* restrict dest, const char* restrict src, size_t count );
|
(desde C99) | |
errno_t strncat_s( char* restrict dest, rsize_t destsz,
const char* restrict src, rsize_t count );
|
(2) | (desde C11) |
1) Añade como máximo
count caracteres del arreglo de caracteres apuntado por src, deteniéndose si se encuentra el carácter nulo, al final de la cadena de bytes terminada en nulo apuntada por dest. El carácter src[0] reemplaza el terminador nulo al final de dest. El carácter nulo de terminación siempre se añade al final (por lo que el número máximo de bytes que la función puede escribir es count + 1). El comportamiento no está definido si el arreglo de destino no tiene suficiente espacio para el contenido de
dest y los primeros count caracteres de src, más el carácter nulo de terminación. El comportamiento no está definido si los objetos de origen y destino se superponen. El comportamiento no está definido si dest no es un puntero a una cadena de bytes terminada en nulo o src no es un puntero a un arreglo de caracteres,2) Igual que (1), excepto que esta función puede sobrescribir el resto del arreglo de destino (desde el último byte escrito hasta
destsz) y que los siguientes errores se detectan en tiempo de ejecución y llaman a la función gestor de restricciones actualmente instalada:
srcodestes un puntero nulodestszocountes cero o mayor que RSIZE_MAX- no hay ningún carácter nulo en los primeros
destszbytes dedest - se produciría truncamiento:
counto la longitud desrc, el que sea menor, excede el espacio disponible entre el terminador nulo dedestydestsz. - se produciría superposición entre la cadena de origen y la de destino
El comportamiento no está definido si el tamaño del arreglo de caracteres apuntado por
dest < strnlen(dest, destsz) + strnlen(src,count) + 1 < destsz; en otras palabras, un valor erróneo de destsz no expone el desbordamiento de búfer inminente. El comportamiento no está definido si el tamaño del arreglo de caracteres apuntado por src < strnlen(src,count) < destsz; en otras palabras, un valor erróneo de count no expone el desbordamiento de búfer inminente. Como con todas las funciones con verificación de límites,
strncat_s solo está garantizado de estar disponible si __STDC_LIB_EXT1__ está definido por la implementación y si el usuario define __STDC_WANT_LIB_EXT1__ como la constante entera 1 antes de incluir <string.h>.Parámetros
| dest | - | puntero a la cadena de bytes terminada en nulo a la que se va a añadir |
| src | - | puntero al arreglo de caracteres desde el que copiar |
| count | - | número máximo de caracteres a copiar |
| destsz | - | el tamaño del búfer de destino |
Valor de retorno
1) devuelve una copia de
dest2) devuelve cero en caso de éxito, devuelve distinto de cero en caso de error. Además, en caso de error, escribe cero en
dest[0] (a menos que dest sea un puntero nulo o destsz sea cero o mayor que RSIZE_MAX).Notas
Porque strncat necesita buscar hasta el final de dest en cada llamada, es ineficiente concatenar muchas cadenas en una sola usando strncat.
Aunque el truncamiento para ajustarse al búfer de destino es un riesgo de seguridad y por lo tanto una violación de restricciones en tiempo de ejecución para strncat_s, es posible obtener el comportamiento de truncamiento especificando count igual al tamaño del arreglo de destino menos uno: copiará los primeros count bytes y añadirá el terminador nulo como siempre: strncat_s(dst, sizeof dst, src, (sizeof dst) - strnlen_s(dst, sizeof dst) - 1);
Ejemplo
Ejecutar este código
#define __STDC_WANT_LIB_EXT1__ 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char str[50] = "Hello ";
char str2[50] = "World!";
strcat(str, str2);
strncat(str, " Goodbye World!", 3);
puts(str);
#ifdef __STDC_LIB_EXT1__
set_constraint_handler_s(ignore_handler_s);
char s1[100] = "good";
char s5[1000] = "bye";
int r1 = strncat_s(s1, 100, s5, 1000); // r1 is 0, s1 holds "goodbye\0"
printf("s1 = %s, r1 = %d\n", s1, r1);
char s2[6] = "hello";
int r2 = strncat_s(s2, 6, "", 1); // r2 is 0, s2 holds "hello\0"
printf("s2 = %s, r2 = %d\n", s2, r2);
char s3[6] = "hello";
int r3 = strncat_s(s3, 6, "X", 2); // r3 is non-zero, s3 holds "\0"
printf("s3 = %s, r3 = %d\n", s3, r3);
// the strncat_s truncation idiom:
char s4[7] = "abc";
int r4 = strncat_s(s4, 7, "defghijklmn", 3); // r4 is 0, s4 holds "abcdef\0"
printf("s4 = %s, r4 = %d\n", s4, r4);
#endif
}
Posible salida:
Hello World! Go
s1 = goodbye, r1 = 0
s2 = hello, r2 = 0
s3 = , r3 = 22
s4 = abcdef, r4 = 0
Referencias
- Estándar C23 (ISO/IEC 9899:2024):
- 7.26.3.2 La función strncat (p: 379)
- K.3.7.2.2 La función strncat_s (p: TBD)
- Estándar C17 (ISO/IEC 9899:2018):
- 7.24.3.2 La función strncat (p: 265-266)
- K.3.7.2.2 La función strncat_s (p: 449-450)
- Estándar C11 (ISO/IEC 9899:2011):
- 7.24.3.2 La función strncat (p: 364-365)
- K.3.7.2.2 La función strncat_s (p: 618-620)
- Estándar C99 (ISO/IEC 9899:1999):
- 7.21.3.2 La función strncat (p: 327-328)
- Estándar C89/C90 (ISO/IEC 9899:1990):
- 4.11.3.2 La función strncat
Véase también
(C11) |
concatena dos cadenas (función) |
(C11) |
copia una cadena en otra (función) |
(C23) |
copia un búfer en otro, deteniéndose después del delimitador especificado (función) |
Documentación de C++ para strncat
| |