Namespaces
Variants

strncpy, strncpy_s

From cppreference.net
< c ‎ | string ‎ | byte
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)
1) Copia como máximo 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 .
Si count se alcanza antes de que se copie todo el arreglo src , el arreglo de caracteres resultante no termina en nulo.
Si, después de copiar el carácter nulo de terminación desde src , count no se alcanza, se escriben caracteres nulos adicionales en dest hasta que se hayan escrito un total de count caracteres.
El comportamiento es indefinido si los arreglos de caracteres se superponen, si 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.
2) Igual que (1) , excepto que la función no continúa escribiendo ceros en el array de destino para rellenar hasta 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:
  • src o dest es un puntero nulo
  • destsz es cero o mayor que RSIZE_MAX
  • count es mayor que RSIZE_MAX
  • count es mayor o igual que destsz , pero destsz es menor o igual que strnlen_s ( src, count ) , en otras palabras, ocurriría truncamiento
  • ocurriría superposición entre las cadenas fuente y destino
El comportamiento es indefinido si el tamaño del array de caracteres apuntado por 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_s solo 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

1) devuelve una copia de dest
2) retorna cero en caso de éxito, retorna 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 ) 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

copia una cadena a otra
(función)
copia un búfer a otro
(función)
(dynamic memory TR)
asigna una copia de una cadena hasta un tamaño especificado
(función)