strncpy, strncpy_s
|
Definido en el encabezado
<string.h>
|
||
| (1) | ||
|
char
*
strncpy
(
char
*
dest,
const
char
*
src,
size_t
count
)
;
|
(hasta C99) | |
|
char
*
strncpy
(
char
*
restrict
dest,
const
char
*
restrict
src,
size_t
count
)
;
|
(desde C99) | |
|
errno_t strncpy_s
(
char
*
restrict
dest, rsize_t destsz,
const char * restrict src, rsize_t count ) ; |
(2) | (desde C11) |
count
caracteres del array de caracteres apuntado por
src
(incluyendo el carácter nulo terminador, pero no ninguno de los caracteres que siguen al carácter nulo) al array de caracteres apuntado por
dest
.
count
se alcanza antes de que se copie todo el arreglo
src
, el arreglo de caracteres resultante no termina en nulo.
src
,
count
no se alcanza, se escriben caracteres nulos adicionales en
dest
hasta que se hayan escrito un total de
count
caracteres.
dest
o
src
no son punteros a un arreglo de caracteres (incluyendo si
dest
o
src
son punteros nulos), si el tamaño del arreglo apuntado por
dest
es menor que
count
, o si el tamaño del arreglo apuntado por
src
es menor que
count
y no contiene un carácter nulo.
count
, se detiene después de escribir el carácter nulo terminador (si no había un nulo en la fuente, escribe uno en
dest
[
count
]
y luego se detiene). Además, los siguientes errores se detectan en tiempo de ejecución y llaman a la función
constraint handler
actualmente instalada:
-
-
srcodestes un puntero nulo -
destszes cero o mayor que RSIZE_MAX -
countes mayor que RSIZE_MAX -
countes mayor o igual quedestsz, perodestszes menor o igual que strnlen_s ( src, count ) , en otras palabras, ocurriría truncamiento - ocurriría superposición entre las cadenas fuente y destino
-
dest
<
strnlen_s
(
src, destsz
)
<=
destsz
; en otras palabras, un valor erróneo de
destsz
no expone el desbordamiento de búfer inminente. El comportamiento es indefinido si el tamaño del array de caracteres apuntado por
src
<
strnlen_s
(
src, count
)
<
destsz
; en otras palabras, un valor erróneo de
count
puede permitir un desbordamiento de búfer.
-
Como con todas las funciones con verificación de límites,
strncpy_ssolo está garantizada su disponibilidad 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> .
Contenidos |
Parámetros
| dest | - | puntero al array de caracteres donde copiar |
| src | - | puntero al array de caracteres desde donde copiar |
| count | - | número máximo de caracteres a copiar |
| destsz | - | tamaño del buffer de destino |
Valor de retorno
dest
dest
sea un puntero nulo o
destsz
sea cero o mayor que
RSIZE_MAX
) y puede sobrescribir el resto del array de destino con valores no especificados.
Notas
Como se corrigió mediante el post-C11 DR 468,
strncpy_s
, a diferencia de
strcpy_s
, solo tiene permitido sobrescribir el resto del array de destino si ocurre un error.
A diferencia de
strncpy
,
strncpy_s
no rellena el arreglo de destino con ceros. Esta es una fuente común de errores al convertir código existente a la versión con verificación de límites.
Aunque el truncamiento para ajustarse al búfer de destino es un riesgo de seguridad y por tanto una violación de restricciones en tiempo de ejecución para
strncpy_s
,
es posible obtener el comportamiento de truncamiento especificando
count
igual al tamaño del array de destino menos uno: copiará los primeros
count
bytes y añadirá el terminador nulo como siempre:
strncpy_s
(
dst,
sizeof
dst, src,
(
sizeof
dst
)
-
1
)
;
Ejemplo
#define __STDC_WANT_LIB_EXT1__ 1 #include <string.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> int main(void) { char src[] = "hi"; char dest[6] = "abcdef"; // sin terminador nulo strncpy(dest, src, 5); // escribe cinco caracteres 'h', 'i', '\0', '\0', '\0' en dest printf("strncpy(dest, src, 5) a un dest de 6 bytes da: "); for (size_t n = 0; n < sizeof dest; ++n) { char c = dest[n]; c ? printf("'%c' ", c) : printf("'\\0' "); } printf("\nstrncpy(dest2, src, 2) a un dst de 2 bytes da: "); char dest2[2]; strncpy(dest2, src, 2); // truncamiento: escribe dos caracteres 'h', 'i' en dest2 for (size_t n = 0; n < sizeof dest2; ++n) { char c = dest2[n]; c ? printf("'%c' ", c) : printf("'\\0' "); } printf("\n"); #ifdef __STDC_LIB_EXT1__ set_constraint_handler_s(ignore_handler_s); char dst1[6], src1[100] = "hello"; errno_t r1 = strncpy_s(dst1, 6, src1, 100); // escribe 0 en r1, 6 caracteres en dst1 printf("dst1 = \"%s\", r1 = %d\n", dst1,r1); // 'h','e','l','l','o','\0' a dst1 char dst2[5], src2[7] = {'g','o','o','d','b','y','e'}; errno_t r2 = strncpy_s(dst2, 5, src2, 7); // la copia desborda el array de destino printf("dst2 = \"%s\", r2 = %d\n", dst2,r2); // escribe distinto de cero en r2, '\0' en dst2[0] char dst3[5]; errno_t r3 = strncpy_s(dst3, 5, src2, 4); // escribe 0 en r3, 5 caracteres en dst3 printf("dst3 = \"%s\", r3 = %d\n", dst3,r3); // 'g', 'o', 'o', 'd', '\0' a dst3 #endif }
Salida posible:
strncpy(dest, src, 5) a un dst de 6 bytes da: 'h' 'i' '\0' '\0' '\0' 'f' strncpy(dest2, src, 2) a un dst de 2 bytes da: 'h' 'i' dst1 = "hello", r1 = 0 dst2 = "", r2 = 22 dst3 = "good", r3 = 0
Referencias
- Estándar C17 (ISO/IEC 9899:2018):
-
- 7.24.2.4 La función strncpy (p: 265)
-
- K.3.7.1.4 La función strncpy_s (p: 447-448)
- Estándar C11 (ISO/IEC 9899:2011):
-
- 7.24.2.4 La función strncpy (p: 363-364)
-
- K.3.7.1.4 La función strncpy_s (p: 616-617)
- Estándar C99 (ISO/IEC 9899:1999):
-
- 7.21.2.4 La función strncpy (p: 326-327)
- Estándar C89/C90 (ISO/IEC 9899:1990):
-
- 4.11.2.4 La función strncpy
Véase también
|
(C11)
|
copia una cadena a otra
(función) |
|
(C11)
|
copia un búfer a otro
(función) |
|
(dynamic memory TR)
|
asigna una copia de una cadena hasta un tamaño especificado
(función) |
|
Documentación de C++
para
strncpy
|
|