elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Como proteger una cartera - billetera de Bitcoin


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  dudas con strcpy
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] 2 Ir Abajo Respuesta Imprimir
Autor Tema: dudas con strcpy  (Leído 5,582 veces)
m@o_614


Desconectado Desconectado

Mensajes: 389


Ver Perfil
dudas con strcpy
« en: 15 Marzo 2014, 19:31 pm »

Saludos

tengo una duda con respecto al uso de strcpy

si tengo una cadena por ejemplo:

char *cadena = "hola mundo";

y despues quiero cambiar el contenido de esa cadena, puedo usar el strcpy para eso??

strcpy(cadena,"lo que quieras escribir");

gracias


En línea

Yoel Alejandro

Desconectado Desconectado

Mensajes: 254



Ver Perfil WWW
Re: dudas con strcpy
« Respuesta #1 en: 15 Marzo 2014, 20:32 pm »

Ok, hay varios aspectos implícitos en tu pregunta. La función

strcpy( char *s1, const char *s2)

copia el contenido de s2 en s1, añadiendo al final de s1 un carácter nulo de terminación '\0'. La única consideración es que s1 contenga el suficiente espacio disponible para copiar todos los caracteres (al menos la longitud de s2 más uno).

Esto por supuesto requiere que se pueda escribir en el espacio asignado a s1. Si declaras

char *cadena = "hola mundo";

entonces cadena se considerará un string constante y ya no podrás escribir nada nuevo en él. Pero la declaración:

char cadena[] = "hola mundo";

sí permite rescribir el contenido de cadena (siempre y cuando la nueva cadena sea de longitud menor o igual a la que tenías primero, de lo contrario no habrá espacio disponible suficiente). Por ejemplo, puedes poner:

strcpy( cadena, "Pepe");
puts( cadena );

y verás como ahora escribe "Pepe".

----------------------------------------------------------------------------------
NOTA. En cuánto a la declaración de string constantes no se con exactitud si la forma de interpretar la sentencia depende del compilador o de la versión de C, o de si es en C ó en C++. Que alguno de los usuarios más versados en el tema por favor nos complemente.


En línea

Saludos, Yoel.
P.D..-   Para mayores dudas, puedes enviarme un mensaje personal (M.P.)
milx86

Desconectado Desconectado

Mensajes: 42


Ver Perfil
Re: dudas con strcpy
« Respuesta #2 en: 15 Marzo 2014, 20:48 pm »

Concuerdo con yoel, tienes que tener en cuenta 2 puntos importantes:

1. Cito: "Es nuestra responsabilidad que en la cadena de destino haya suficiente espacio reservado para copiar lo que queremos. Si no es así, estaremos sobreescribiendo direcciones de memoria en las que no sabemos qué hay."
Fuente http://www.nachocabanes.com/c/curso/cc05.php

Asi que mejor te recomiendo usar strncpy.

2. Estas declarando una constante de caracteres que no puedes modificar.
Para no hacer copia y pega, te invito a leer esto, no es mucho y estoy seguro aclarará un poco más tus dudas.
Fuente: http://es.wikibooks.org/wiki/Programaci%C3%B3n_en_C/Punteros#Punteros_a_cadenas_de_caracteres

Suerte. :D
En línea

La abstracción es la clave para lidiar con la complejidad.
leosansan


Desconectado Desconectado

Mensajes: 1.314


Ver Perfil
Re: dudas con strcpy
« Respuesta #3 en: 15 Marzo 2014, 21:21 pm »

Concuerdo con yoel, tienes que tener en cuenta 2 puntos importantes:
......................................

Totalmente de acuerdo con ambos. Cito una indicación de la página de
cplusplus :

Citar

strcpy

char * strcpy ( char * destination, const char * source );

Copy string
Copies the C string pointed by source into the array pointed by destination, including the terminating null character (and stopping at that point).

To avoid overflows, the size of the array pointed by destination shall be long enough to contain the same C string as source (including the terminating null character), and should not overlap in memory with source.



Sin embargo ..... supongo que es el propio compilador el que lleva a cabo la operación de ampliar el espacio de la cadena receptora, que en principio es de 10 y podría provocar el overflow, pero en la práctica eso no sucede.

Está es la salida al código de ejemplo:


Citar

Cadena str1 antes del cambio:
A ver si cabe la cadena str1 en srt2

Cadena str2 antes del cambio:
leosansan

Lo que queda en str1: abe la cadena str1 en srt2

Copiado, nuevo str2:
A ver si cabe la cadena str1 en srt2



Y la cadena str2 impresa caracter a caracter:
 A ver si cabe la cadena str1 en srt2

longitud de la nueva cadena str2=
36
Process returned 0 (0x0)   execution time : 1.500 s
Press any key to continue.


Como pueden observar, str2 "se metió" en la cadena str1 que originalmente erra de dimensión 10 sin problemas.

Eso si, destacar que si str2 no tiene suficiente dimensión quedará en la  cadena original el "resto" de la dicha cadena:


Código
  1. #include <stdio.h>
  2. #include <string.h>
  3. int main ()
  4. {
  5.    int i;
  6.    char str1[ ]="A ver si cabe la cadena str1 en srt2";
  7.    char str2[10]="leosansan";
  8.    printf ("\nCadena str1 antes del cambio:\n%s",str1);
  9.    printf ("\n\nCadena str2 antes del cambio:\n%s",str2);
  10.    strcpy (str2,str1);
  11.    printf ("\n\nLo que queda en str1: %s\n\nCopiado, nuevo str2:\n%s\n\n",str1,str2);
  12.    printf("\n\nY la cadena str2 impresa caracter a caracter:\n ");
  13.    for( i=0;str2[i]; i++)
  14.      printf( "%c",str2[i] );
  15.    printf( "\n\nlongitud de la nueva cadena str2=\n%d", strlen(str2) );
  16.    return 0;
  17. }

Espero no haberme liado con este rollito, ¿o tal vez si?. Ya me contaran ustedes.

¡¡¡¡ Saluditos! ..... !!!!



En línea

amchacon


Desconectado Desconectado

Mensajes: 1.211



Ver Perfil
Re: dudas con strcpy
« Respuesta #4 en: 15 Marzo 2014, 21:33 pm »

NOTA. En cuánto a la declaración de string constantes no se con exactitud si la forma de interpretar la sentencia depende del compilador o de la versión de C, o de si es en C ó en C++. Que alguno de los usuarios más versados en el tema por favor nos complemente.
Te refieres a:
Código
  1. char *cadena = "hola mundo";

En ningún compilador de C/C++ podrás modificar el contenido de cadena. Más que nada porque lo que estás haciendo es declarar un puntero que apunta a una cadena literal (y los valores literales son constantes por definición).

Excepción los arrays de chars, donde por comodidad sintáctica se te permite escribir esta sentencia:
Código
  1. char cadena[] = {'h','o','l','a',' ','m','u','n','d','o','\0'};

De esta forma:
Código
  1. char cadena[] = "hola mundo";

Totalmente de acuerdo con ambos. Cito una indicación de la página de
cplusplus :

Sin embargo ..... supongo que es el propio compilador el que lleva a cabo la operación de ampliar el espacio de la cadena receptora, que en principio es de 10 y podría provocar el overflow, pero en la práctica eso no sucede.

Está es la salida al código de ejemplo:


Como pueden observar, str2 "se metió" en la cadena str1 que originalmente erra de dimensión 10 sin problemas.

Eso si, destacar que si str2 no tiene suficiente dimensión quedará en la  cadena original el "resto" de la dicha cadena:


Código
  1. #include <stdio.h>
  2. #include <string.h>
  3. int main ()
  4. {
  5.    int i;
  6.    char str1[ ]="A ver si cabe la cadena str1 en srt2";
  7.    char str2[10]="leosansan";
  8.    printf ("\nCadena str1 antes del cambio:\n%s",str1);
  9.    printf ("\n\nCadena str2 antes del cambio:\n%s",str2);
  10.    strcpy (str2,str1);
  11.    printf ("\n\nLo que queda en str1: %s\n\nCopiado, nuevo str2:\n%s\n\n",str1,str2);
  12.    printf("\n\nY la cadena str2 impresa caracter a caracter:\n ");
  13.    for( i=0;str2[i]; i++)
  14.      printf( "%c",str2[i] );
  15.    printf( "\n\nlongitud de la nueva cadena str2=\n%d", strlen(str2) );
  16.    return 0;
  17. }

Espero no haberme liado con este rollito, ¿o tal vez si?. Ya me contaran ustedes.
Pues si te has liado, prueba este otro código:

Código
  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. int main ()
  5. {
  6.    int i;
  7.    char str1[ ]="Cosita grande y hermosa";
  8.    char str2[10]="leosansan";
  9.  
  10.    printf ("\nCadena str1 antes del cambio:\n%s",str1);
  11.    printf ("\n\nCadena str2 antes del cambio:\n%s",str2);
  12.    strcpy (str2,str1);
  13.    printf ("\n\nLo que queda en str1: %s\n\nCopiado, nuevo str2:\n%s\n\n",str1,str2);
  14.    printf("\n\nY la cadena str2 impresa caracter a caracter:\n ");
  15.    for( i=0; str2[i]; i++)
  16.        printf( "%c",str2[i] );
  17.    printf( "\n\nlongitud de la nueva cadena str2=\n%d\n", strlen(str2) );
  18.  
  19.    return 0;
  20. }
  21.  

Fijate en el contenido de str1:
Citar
nde y hermosa

Ha dado overflow, te has salido del espacio de str2 y estás sobreescribiendo la cadena str1.

¿Por que en el otro ejemplo si funcionaba? Pues porque lo has interpretado mal:
Citar
A ver si cabe la cadena str1 en srt2
abe la cadena str1 en srt2

Se ha comido lo que está en negrita, lo que pasa esque no suena raro y lo has pasado por alto sin darte cuenta.
« Última modificación: 15 Marzo 2014, 21:34 pm por amchacon » En línea

Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar
Yoel Alejandro

Desconectado Desconectado

Mensajes: 254



Ver Perfil WWW
Re: dudas con strcpy
« Respuesta #5 en: 15 Marzo 2014, 21:44 pm »

En el caso que plantea leosansan, supongo que dependerá del compilador. Probablemente cualquier compilador moderno tomará previsiones adecuadas si la cadena de origen excede en longitud a la cadena de destino.

Sin embargo la filosofía de C es que "los programadores saben lo que están haciendo", por eso pienso que a pesar de la ayuda que pueda proporcionar el compilador, un buen programador de C debe garantizarse por sí mismo la consistencia de este tipo de operaciones. Así que al autor del post: pues, ya lo sabes!!!

Interesante un detalle adicional de la cita de cplusplus y que se me había pasado por alto: Las cadenas origen y destino no deben solaparse. Esta es otra consideración a tener en cuenta, no se debe intentar escribir una cadena sobre sí misma.

NOTA: Estas dificultades se evitan cómodamente usando la clase string de C++. Pero personalmente creo que quién se quiera formar como un verdadero programador debería pasar primero por C (con todas sus dificultades asociadas), y luego ir a C++. Hay que "ensuciarse" primero para aprender bien. Bueno, al menos es mi criterio, no se qué opinen los demás (?)
En línea

Saludos, Yoel.
P.D..-   Para mayores dudas, puedes enviarme un mensaje personal (M.P.)
amchacon


Desconectado Desconectado

Mensajes: 1.211



Ver Perfil
Re: dudas con strcpy
« Respuesta #6 en: 15 Marzo 2014, 22:40 pm »

En el caso que plantea leosansan, supongo que dependerá del compilador. Probablemente cualquier compilador moderno tomará previsiones adecuadas si la cadena de origen excede en longitud a la cadena de destino.
Eso no es así, ya se lo desmentí a Leosan.

Hacer esas aproximaciones suele dar muy malos resultados. Luego ocurren los errores extraños y inexplicables, los crasheos aleatorios...

Como regla general, siempre hay que ceñirse a lo que te diga el creador de la función. Cualquier truco o atajo que intentes no está garantizado contra errores y probablemente acabe muy mal.

Estas dificultades se evitan cómodamente usando la clase string de C++. Pero personalmente creo que quién se quiera formar como un verdadero programador debería pasar primero por C (con todas sus dificultades asociadas), y luego ir a C++. Hay que "ensuciarse" primero para aprender bien. Bueno, al menos es mi criterio, no se qué opinen los demás (?)
Un buen programador es el que es capaz de escribir la solución de un problema paso a paso. El usar un lenguaje u otro solo sirve para probar tu solución en una computadora.

Lo que si es verdad esque es importante conocer los mecanismos de abstracción (grafos, listas, vectores...). Y una forma práctica de aprenderlo es re-hacer la librería básica del lenguaje.

PD: Un buen programador no tiene problemas en adaptarse de un lenguaje a otro en poco tiempo. Aunque no lo haya visto nunca, normalmente son todos muy parecidos.
En línea

Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar
leosansan


Desconectado Desconectado

Mensajes: 1.314


Ver Perfil
Re: dudas con strcpy
« Respuesta #7 en: 15 Marzo 2014, 23:24 pm »

................................................

Fijate en el contenido de str1:
Ha dado overflow, te has salido del espacio de str2 y estás sobreescribiendo la cadena str1.

¿Por que en el otro ejemplo si funcionaba? Pues porque lo has interpretado mal:
Se ha comido lo que está en negrita, lo que pasa es que no suena raro y lo has pasado por alto sin darte cuenta.

La salida tuya:

Citar

Cadena str1 antes del cambio:
Cosita grande y hermosa

Cadena str2 antes del cambio:
leosansan

Lo que queda en str1: nde y hermosa

Copiado, nuevo str2:
Cosita grande y hermosa



Y la cadena str2 impresa caracter a caracter:
 Cosita grande y hermosa

longitud de la nueva cadena str2=
23

Process returned 0 (0x0)   execution time : 0.102



Por ejemplo esta otra salida:

Citar

Cadena str1 antes del cambio:
Cosita grande y hermosa

Cadena str2 antes del cambio:
leosansan

Lo que queda en str1: nde y hermosa

Copiado, nuevo str2:
Cosita grande y hermosa



Y la cadena str2 impresa caracter a caracter:
 Cosita grande y hermosa

Cadena str0 despues del cambio:

Gran Canaria es Cosita grande y hermosa

Cadena str3 despues del cambio:

leosansan es de Gran Canaria


Process returned 0 (0x0)   execution time : 1.165 s
Press any key to continue.



A este código:

Código
  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. int main ()
  5. {
  6.    int i;
  7.    char str0[ ]="Gran Canaria es Cosita grande y hermosa";
  8.    char str1[  ]="Cosita grande y hermosa";
  9.    char str2[ ]="leosansan";
  10.    char str3[ ]="leosansan es de Gran Canaria";
  11.  
  12.    printf ("\nCadena str1 antes del cambio:\n%s",str1);
  13.    printf ("\n\nCadena str2 antes del cambio:\n%s",str2);
  14.    strcpy (str2,str1);
  15.    printf ("\n\nLo que queda en str1: %s\n\nCopiado, nuevo str2:\n%s\n\n",str1,str2);
  16.    printf("\n\nY la cadena str2 impresa caracter a caracter:\n ");
  17.    for( i=0; str2[i]; i++)
  18.        printf( "%c",str2[i] );
  19.    printf( "\n\nCadena str0 despues del cambio:\n\n%s",str0);
  20.    printf ("\n\nCadena str3 despues del cambio:\n\n%s\n\n",str3);
  21.    return 0;
  22. }

Lo realmente raro es que si declaro varias cadenas str, tres o cuatro, además de str1 y str2, lo que queda en str1 siempre es el resto de lo que teóricamente "sobra en str2, en tu ejemplo y en el mio. Será casualidad o no, pero es un resultado cuando menos inesperado. ¿Por qué juntamente queda en str1 y no en las otras cadenas que he declarado?. He ahí mi gran duda, ¿será casualidad o es un comportamiento normal de la función strcpy "dejar" el resto de la cadena que no quepa en str2?. Y a los ejemplos me remito, claro que tan sólo son dos ejemplos y ya sabemos que no se puede pasr del particular al general, pero ......

Pero lo que dice el manual está claro, yo sólo pongo de manifiesto un hecho contrastado en esos dos ejemplos.


¡¡¡¡ Saluditos! ..... !!!!


En línea

Yoel Alejandro

Desconectado Desconectado

Mensajes: 254



Ver Perfil WWW
Re: dudas con strcpy
« Respuesta #8 en: 15 Marzo 2014, 23:26 pm »

Amchacon, por eso dije ... "supongo", porque la verdad yo no se.

No lo se porque en lo particular siempre trato de programar de forma "segura", atendiendo a las especificaciones de la biblioteca estándar de C, y la verdad pocas veces me he puesto a ver qué pasa si hago tal o cuál cosa de manera insegura. Prefiero irme de una vez por lo sano, y así evitar crasheos, etc.

Pero respecto a lo de varios lenguajes lo que quise decir es que específicamente en el aprendizaje de C/C++, me parece más adecuado aprender primero a programar correctamente en C, y luego pasarse a C++ el cual básicamente amplica las capacidades del primero. Eso en lugar de mezclar el C y el C++, lo que constituye una mala costumbre según el criterio unánime creo que todos los que opinamos aquí.

Otra mala costumbre, y lamentablemente extendida entre algunos maestros, es no guiarse por el C estándar. Referirse a gotoxy(), getch(), etc., de la manera más natural (y descarada), sin especificar ni aclarar que son no funciones estándares. No digo que no usen esas funciones, pero deben dejar en claro que son privativas y generalmente usadas en Windows.
« Última modificación: 15 Marzo 2014, 23:29 pm por yoel_alejandro » En línea

Saludos, Yoel.
P.D..-   Para mayores dudas, puedes enviarme un mensaje personal (M.P.)
amchacon


Desconectado Desconectado

Mensajes: 1.211



Ver Perfil
Re: dudas con strcpy
« Respuesta #9 en: 15 Marzo 2014, 23:50 pm »

He ahí mi gran duda, ¿será casualidad o es un comportamiento normal de la función strcpy "dejar" el resto de la cadena que no quepa en str2?. Y a los ejemplos me remito, claro que tan sólo son dos ejemplos y ya sabemos que no se puede pasr del particular al general, pero ....
Tengo una teoría.

Suponte este caso:

Código
  1. char inicia[] = "Entrada larga";
  2. char destino[5] = "abcd";

La memoria podría ser:
Citar
00 a   --> Destino
01 b
02 c
03 d
04 '\0'
05 E   --> Original
06 n
07 t
08 r
09 a
10 ' '
11 l
12 a
13 r
14 g
15 a
16 '\0'

Y hacemos el strcpy:

Citar
00 E    --> Destino
01 n
02 t
03 r
04 a
05 d    --> Original
06 a
07 ' '
08 l
09 a
10 r
11 g
12 a
13 '\0'
14 g
15 a
16 '\0'

Fijate que el puntero "original" apunta a las ultimas posiciones de "destino".

No esque deje lo que sobre, esque estamos viendo los ultimos caracteres de la cadena destino!

Lo acabo de probar y efectivamente str1 da la salida que esperaba: "da larga"
Código
  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. int main ()
  5. {
  6.    char str1[] = "Entrada larga";
  7.    char str2[5] = "abcd";
  8.  
  9.    strcpy (str2,str1);
  10.    printf ("\n\nLo que queda en str1: %s\n\nCopiado, nuevo str2:\n%s\n\n",str1,str2);
  11.    printf("\n\nY la cadena str2 impresa caracter a caracter:\n ");
  12.    int i;
  13.    for( i=0; str2[i]; i++)
  14.        printf( "%c",str2[i] );
  15.    return 0;
  16. }
  17.  

Podríamos "rematar" la teoría modificando un valor de str2. A ver si esos cambios aparecen en str1:

Código
  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. int main ()
  5. {
  6.    char str1[] = "Entrada larga";
  7.    char str2[5] = "abcd";
  8.  
  9.    strcpy (str2,str1);
  10.  
  11.  
  12.    str2[10] = 'Z';
  13.  
  14.    printf ("\n\nLo que queda en str1: %s\n\nCopiado, nuevo str2:\n%s\n\n",str1,str2);
  15.    printf("\n\nY la cadena str2 impresa caracter a caracter:\n ");
  16.    int i;
  17.    for( i=0; str2[i]; i++)
  18.        printf( "%c",str2[i] );
  19.    return 0;
  20. }
  21.  

Cuya salida es:



¡La Z aparece en las dos cadenas! Parece que mi teoria tiene sentido : )

No lo se porque en lo particular siempre trato de programar de forma "segura", atendiendo a las especificaciones de la biblioteca estándar de C, y la verdad pocas veces me he puesto a ver qué pasa si hago tal o cuál cosa de manera insegura. Prefiero irme de una vez por lo sano, y así evitar crasheos, etc.
Eso está bien ^^

Pero respecto a lo de varios lenguajes lo que quise decir es que específicamente en el aprendizaje de C/C++, me parece más adecuado aprender primero a programar correctamente en C, y luego pasarse a C++ el cual básicamente amplica las capacidades del primero. Eso en lugar de mezclar el C y el C++, lo que constituye una mala costumbre según el criterio unánime creo que todos los que opinamos aquí.
Bueno yo hize eso, aunque mucha gente empezó a programar en Python o en Java.

Luego no tuvieron problema en pasar de un lenguaje a otro. Como siempre, lo importante no es el lenguaje sino en saber describir la solución a un problema.

Otra mala costumbre, y lamentablemente extendida entre algunos maestros, es no guiarse por el C estándar. Referirse a gotoxy(), getch(), etc., de la manera más natural (y descarada), sin especificar ni aclarar que son no funciones estándares. No digo que no usen esas funciones, pero deben dejar en claro que son privativas y generalmente usadas en Windows.
+1, totalmente de acuerdo.
En línea

Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar
Páginas: [1] 2 Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Problema con funcion strcpy().
Programación C/C++
dark-heimdall 1 5,018 Último mensaje 19 Febrero 2011, 06:36 am
por dark-heimdall
problema con uso de strcpy
Programación C/C++
m@o_614 2 2,810 Último mensaje 19 Diciembre 2011, 18:37 pm
por m@o_614
strcpy entre char
Programación C/C++
Jupiter34 5 2,645 Último mensaje 1 Noviembre 2012, 03:44 am
por BatchianoISpyxolo
strcpy en puntero matriz
Programación C/C++
psycho248 9 4,740 Último mensaje 24 Junio 2014, 09:22 am
por eferion
ayuda con strcpy en kubuntu
Programación C/C++
Rom_Stom 6 2,999 Último mensaje 15 Junio 2016, 03:47 am
por Rom_Stom
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines