usar resueltos lenguaje leer guardar funciones espacios ejercicios ejemplos con como caracteres cadenas cadena arreglo c++ string g++ char

resueltos - Cómo copiar una cadena en una matriz de caracteres en C++ sin pasar por el búfer



funciones de cadenas de caracteres en c++ (11)

Quiero copiar una cadena en una matriz de caracteres y no sobrepasar el búfer.

Por lo tanto, si tengo una matriz de caracteres de tamaño 5, quiero copiar un máximo de 5 bytes de una cadena en ella.

¿Cuál es el código para hacer eso?


Algunas buenas versiones de libc proporcionan un reemplazo no estándar pero excelente para strcpy(3) / strncpy(3) - strlcpy(3) .

Si el suyo no lo tiene, el código fuente está disponible gratuitamente here desde el repositorio de OpenBSD .


Creo que snprintf () es mucho más seguro y simple.

snprintf ( buffer, 100, "The half of %d is %d", 60, 60/2 );

el carácter nulo se anexa finaliza automáticamente :)


Esto es exactamente lo que hace la función de copia de std::string .

#include <string> #include <iostream> int main() { char test[5]; std::string str( "Hello, world" ); str.copy(test, 5); std::cout.write(test, 5); std::cout.put(''/n''); return 0; }

Si necesita una terminación nula debe hacer algo como esto:

str.copy(test, 4); test[4] = ''/0'';


Si siempre tienes un búfer de tamaño 5, entonces podrías hacer:

std::string s = "Your string"; char buffer[5]={s[0],s[1],s[2],s[3],''/0''};

Edición: Por supuesto, asumiendo que su cadena estándar :: es lo suficientemente grande.


Usar funcion strlcpy el enlace roto y el material no se encuentran en el sitio de destino si su implementación proporciona uno (la función no se encuentra en la biblioteca C estándar), aunque es ampliamente aceptado como un nombre estándar de facto para una función de copia de longitud limitada "segura" para cadenas terminadas en cero.

Si su implementación no proporciona la función strlcpy , implemente una. Por ejemplo, algo como esto podría funcionar para usted.

char *my_strlcpy(char *dst, const char *src, size_t n) { assert(dst != NULL && src != NULL); if (n > 0) { char *pd; const char *ps; for (--n, pd = dst, ps = src; n > 0 && *ps != ''/0''; --n, ++pd, ++ps) *pd = *ps; *pd = ''/0''; } return dst; }

(En realidad, el strlcpy aceptado de facto devuelve size_t , por lo que es posible que prefiera implementar la especificación aceptada en lugar de lo que hice anteriormente).

Tenga cuidado con las respuestas que recomiendan el uso de strncpy para ese propósito. strncpy no es una función segura de copia de cadenas de longitud limitada y no debe utilizarse para ese propósito. Si bien puede forzar a strncpy a "trabajar" para ese propósito, todavía es similar a conducir tornillos de madera con un martillo.


Actualización: pensé que intentaría unir algunas de las respuestas, respuestas que me han convencido de que mi propia respuesta original de Strncpy fue mala.

Primero, como señaló AndreyT en los comentarios a esta pregunta, los métodos de truncamiento (snprintf, strlcpy y strncpy) a menudo no son una buena solución. A menudo es mejor verificar el tamaño de la cadena string.size() con la longitud del búfer y devolver / lanzar un error o cambiar el tamaño del búfer.

Si el truncamiento está bien en su situación, en mi humilde opinión, strlcpy es la mejor solución, siendo el método más rápido / con menos gastos generales que garantiza la terminación nula. Desafortunadamente, no está en muchas / todas las distribuciones estándar y, por lo tanto, no es portátil. Si está haciendo muchos de estos, quizás valga la pena proporcionar su propia implementación, AndreyT dio un example . Se ejecuta en O ( longitud del resultado ). Además, la especificación de referencia devuelve el número de bytes copiados, lo que puede ayudar a detectar si la fuente se truncó.

Otras buenas soluciones son sprintf y snprintf . Son estándar, y por lo tanto son portátiles y proporcionan un resultado terminado en nulo seguro. Tienen más sobrecarga que strlcpy (analizando el formato del especificador de cadena y la lista de argumentos variables), pero a menos que esté haciendo muchos de estos, probablemente no notará la diferencia. También se ejecuta en O ( longitud del resultado ). snprintf siempre es seguro y ese sprintf puede desbordarse si el especificador de formato es incorrecto (como han señalado otros, la cadena de formato debe ser "%.<N>s" no "%<N>s" ). Estos métodos también devuelven el número de bytes copiados.

Una solución de caso especial es strncpy . Se ejecuta en O ( longitud del búfer ), porque si llega al final del src, elimina el resto del búfer. Solo es útil si necesita poner a cero la cola del búfer o está seguro de que las longitudes de cadena de origen y de destino son las mismas. También tenga en cuenta que no es seguro ya que no necesariamente termina en nulo la cadena. Si la fuente está truncada, entonces no se agregará nulo, así que llame en secuencia con una asignación nula para garantizar la terminación nula: strncpy(buffer, str.c_str(), BUFFER_LAST); buffer[BUFFER_LAST] = ''/0''; strncpy(buffer, str.c_str(), BUFFER_LAST); buffer[BUFFER_LAST] = ''/0'';


En primer lugar, strncpy es casi seguro que no es lo que quieres. strncpy fue diseñado para un propósito bastante específico. Está en la biblioteca estándar casi exclusivamente porque ya existe, no porque es generalmente útil.

Probablemente la forma más sencilla de hacer lo que quieres es con algo como:

sprintf(buffer, "%.4s", your_string.c_str());

A diferencia de strncpy , esto garantiza que el resultado se terminará con NUL, pero no completa los datos adicionales en el destino si el origen es más corto que el especificado (aunque este último no es un problema importante cuando la longitud del objetivo es 5).


char mystring[101]; // a 100 character string plus terminator char *any_input; any_input = "Example"; iterate = 0; while ( any_input[iterate] != ''/0'' && iterate < 100) { mystring[iterate] = any_input[iterate]; iterate++; } mystring[iterate] = ''/0'';

Este es el diseño eficiente básico.


void stringChange(string var){ char strArray[100]; strcpy(strArray, var.c_str()); }

Supongo que esto debería funcionar. Copiará la cadena de formulario a una matriz de caracteres.


std::string my_string("something"); char* my_char_array = new char[5]; strncpy(my_char_array, my_string.c_str(), 4); my_char_array[4] = ''/0''; // my_char_array contains "some"

Con strncpy , puede copiar un máximo de n caracteres desde la fuente al destino. Sin embargo, tenga en cuenta que si la cadena de origen tiene un máximo de n caracteres, el destino no se terminará en nulo; usted debe poner el carácter nulo que termina en él mismo.

Una matriz char con una longitud de 5 puede contener a lo sumo una cadena de 4 caracteres, ya que la quinta debe ser el carácter nulo que termina. Por lo tanto, en el código anterior, n = 4.


std::string str = "Your string"; char buffer[5]; strncpy(buffer, str.c_str(), sizeof(buffer)); buffer[sizeof(buffer)-1] = ''/0'';

La última línea es obligatoria porque strncpy no garantiza que NUL termine la cadena (ayer hubo una discusión sobre la motivación).

Si usas cadenas anchas, en lugar de sizeof(buffer) sizeof(buffer)/sizeof(*buffer) , o, mejor aún, una macro como

#define ARRSIZE(arr) (sizeof(arr)/sizeof(*(arr))) /* ... */ buffer[ARRSIZE(buffer)-1]=''/0'';