Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: 7emiliosk8 en 11 Febrero 2017, 22:39 pm



Título: Porque no puedo pasarle la direccion de la cadena? strtol
Publicado por: 7emiliosk8 en 11 Febrero 2017, 22:39 pm
Hola tengo este codigo, se supone que la funcion strtol recibe u puntero doble, pero se supone que la cadena "prueba" es un puntero que apunta  ala direccion de memoria del primer elemento de la cadena, o sea es como si le estuviera pasando la dir de un puntero, no se si me explico , de todos modos no me funciona :/ da un warning

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. int main()
  5. {
  6. char str[30] = "2030300 This is test";
  7. char prueba[20];
  8. char *ptr;
  9. long ret;
  10. printf("\nLa cadena inicial es: %c%s%c\n",34,str,34);
  11.  
  12. /*  long int strtol(const char *str, char **endptr, int base)
  13. //strtol converts the initial part of the string in str to a long int value according to the given base.
  14. whose value is set by the function to the next character in str after the numerical value.
  15. */
  16. ret = strtol(str, &ptr, 10);
  17. printf("\nThe number(unsigned long integer) is %ld\n", ret);
  18. printf("String part is |%s|\n", ptr);
  19.  
  20. ret = strtol(str, &prueba, 10);
  21. printf("\nProbando: %c%s%c\n",34,prueba,34);
  22.  
  23.   return(0);


Título: Re: Porque no puedo pasarle la direccion de la cadena? strtol
Publicado por: class_OpenGL en 11 Febrero 2017, 22:57 pm
Lo que no puedes hacer es pasarle la dirección de un arreglo. Conceptualmente no puedes porque no puedes modificar la dirección de un arreglo.

Nota por si quieres sumar conocimientos (conocimientos obtenidos experimentalmente con el compilador MinGW y MinGW-w64): físicamente no puedes porque un arreglo no guarda una dirección de memoria. En realidad, un arreglo no se almacena en memoria. Al referirte a un elemento del arreglo, el compilador sabe la dirección virtual del primer elemento del arreglo, y por tanto sabe la del elemento. Cuando intentas acceder a la dirección de un arreglo, la dirección que obtienes es la misma dirección del primer elemento del arreglo. Código que lo demuestra:

Código
  1. #include <stdio.h>
  2.  
  3. int main() {
  4.   char arreglo[64];
  5.  
  6.   fprintf(stdout, "El arreglo apunta a:        %p\n", arreglo);
  7.   fprintf(stdout, "El arreglo tiene direccion: %p\n", &arreglo);
  8.  
  9.   return 0;
  10. }

Resultado en pantalla:

Código:
El arreglo apunta a:        000000000023FE10
El arreglo tiene direccion: 000000000023FE10

Espero que se haya entendido


Título: Re: Porque no puedo pasarle la direccion de la cadena? strtol
Publicado por: 7emiliosk8 en 11 Febrero 2017, 23:11 pm
Hola gracias por responder, pero con strtol no estoy modificando la direccion del puntero simplemente llenandolo. poniendo caracteres dentro

Ademas yo lei en una parte que decia, "los arreglos se puede decir que son punteros disfrazados"  ya que el nombre de un arreglo es un puntero a la direccion de memoria del primer elemento del arreglo (que es la misma dir del arreglo), es por eso que cuando
si tengo

char prueba[20];
char *p ;

puedo usar %s de la misma forma que en ambos, printf("%s y %s",prueba,p);
porque prueba se comporta como un puntero. me explico ? entonces no entiendo porque aca no se puede pasar la dir de memoria del arreglo


Título: Re: Porque no puedo pasarle la direccion de la cadena? strtol
Publicado por: class_OpenGL en 11 Febrero 2017, 23:16 pm
Hola gracias por responder, pero con strtol no estoy modificando la direccion del puntero simplemente llenandolo. poniendo caracteres dentro

No, una de las cosas que hace strtol es guardarte en la dirección que le pasas la dirección del primer elemento después del número.

"los arreglos se puede decir que son punteros disfrazados"

Eso se dice para facilitar la comprensión de sintaxis de los arreglos, pero la realidad es la que dije. Un arreglo NO es lo mismo que un puntero. Lo único similar entre ellos es su sintaxis.


Título: Re: Porque no puedo pasarle la direccion de la cadena? strtol
Publicado por: 7emiliosk8 en 11 Febrero 2017, 23:56 pm
No, una de las cosas que hace strtol es guardarte en la dirección que le pasas la dirección del primer elemento después del número.

No te entendi eso muy bien amigo, cuando dices "la direccion del primer elemento despues del numero" podrias detallarlo un poco mas, graciass


Título: Re: Porque no puedo pasarle la direccion de la cadena? strtol
Publicado por: class_OpenGL en 12 Febrero 2017, 00:16 am
Lo que decía hace esto:

1º Se salta todos los espacios que haya en la cadena que le pasas.
2º Te lee y convierte los digitos del numero hasta que se encuentre uno que no sea dígito o cuando llegas al final de la cadena.
3º Te devuelve, además del número, la dirección del primer elemento que se ha encontrado que no es dígito.

Código de ejemplo:

Código
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3.  
  4. int main() {
  5.   char numero_str[] = "124lo que sea";
  6.   int numero;
  7.   char *siguiente;
  8.  
  9.   numero = strtol(numero_str, &siguiente, 10);
  10.  
  11.   fprintf(stdout, "El numero convertido: %i\n", numero);
  12.   fprintf(stdout, "Desplazamiento de \"siguiente\" respecto \"numero_str\": %i\n", (int)siguiente - (int)numero_str);
  13.   fprintf(stdout, "Bytes apuntados por \"siguiente\": '%s'", siguiente);
  14.  
  15.   return 0;
  16. }

Salida:

Código:
El numero convertido: 124
Desplazamiento de "siguiente" respecto "numero_str": 3
Bytes apuntados por "siguiente": 'lo que sea'

Como ves, strtol te ha convertido bien el número.

Lo que decía es que strtol lee dígitos hasta que se encuentre uno que no lo sea. En nuestro ejemplo ("124lo que sea"), strtol lee carácter a carácter. '1' es dígito, convierte y continúa. '2' es dígito, convierte y continúa. '4' es dígito, convierte y continúa. 'l' no es dígito, por lo que para ahí, y devuelve la dirección (que pertenece al arreglo) del elemento 'l'. Como se puede ver en el segundo fprintf, este elemento es el 3.

Nota un poco más técnica: te puedes fijar en el detalle de que la dirección de "siguiente" menos la del arreglo es 3, lo que quiere decir que "siguiente" apunta a 3 bytes más allá del arreglo, y como el arreglo tiene 14 elementos, eso significa que "siguiente" apunta a un elemento del arreglo. Esto deja claro que no se usa memoria dinámica.


Título: Re: Porque no puedo pasarle la direccion de la cadena? strtol
Publicado por: 7emiliosk8 en 12 Febrero 2017, 01:26 am
grnde hermano , muchas gracias, me quedo claro


Título: Re: Porque no puedo pasarle la direccion de la cadena? strtol
Publicado por: 7emiliosk8 en 12 Febrero 2017, 02:37 am
Amigo, mira comente mi codigo, segun lo que tu me explicaste, me podrias decir si esta correcto

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. int main()
  5. {
  6. char str[30] = "2030300 This is test";
  7.  
  8. char *ptr;
  9. long ret;
  10. printf("\nLa cadena inicial es: %c%s%c\n",34,str,34);
  11.  
  12. ret = strtol(str, &ptr, 10); //en simples palabras strtol recibe una cadena que tenga numero y palabra (en ese orden) y el numero que tenga adelante lo retorna como long int, y la palabra siguiente de la cadena la pasa a otra cadena
  13. printf("\nThe number(unsigned long integer) is %ld\n", ret);
  14. printf("String part is |%s|\n", ptr); //ojo que a la cadena le agrego el espacio despues del ..300 This..
  15.  
  16.  
  17. //Que pasa si pongo un char ? por la premisa de que el nombre de un arreglo es un puntero a la dir de mmeoria del primer elemento (la misma la dir de todo el arreglo)
  18. char prueba[20];
  19. ret = strtol(str, &prueba, 10);
  20. printf("\nProbando: %c%s%c\n",34,prueba,34);
  21. /* Da error eso se debe a que para empezar porque Conceptualmente no puedes modificar la dirección de un arreglo, ya que strotl lo que hace es
  22. devuelve, además del número, la dirección del primer elemento que se ha encontrado que no es dígito, o sea de vuelve la direccion de "(espacio)", espacio por que antes de "This" hay un espacio.
  23. como un arreglo se comporta ocmo puntero pero No lo es, lo que estaria diciendo es que prueba ahora apunta a la dir de memoria del "espacio" pero no se puede
  24. si es puntero lo que estoy diciendo en el caso de ptr es que ptr apunta a la dir de memoria de "espacio", es decir p= "dir de memoria del "espacio""
  25. */
  26.  
  27.   return(0);
  28. }
  29.  
  30.  


Título: Re: Porque no puedo pasarle la direccion de la cadena? strtol
Publicado por: class_OpenGL en 12 Febrero 2017, 02:41 am
Sabiendo que esto era el error,

Código
  1. char prueba[20];
  2. ret = strtol(str, &prueba, 10);
  3. printf("\nProbando: %c%s%c\n",34,prueba,34);

Está todo bien.

______________________________________________

Si quieres más información de strtol, te aconsejo visitar el siguiente link:

http://www.cplusplus.com/reference/cstdlib/strtol/ (http://www.cplusplus.com/reference/cstdlib/strtol/)


Título: Re: Porque no puedo pasarle la direccion de la cadena? strtol
Publicado por: 7emiliosk8 en 12 Febrero 2017, 02:55 am
era para saber si estaba bien la logica del porque da ese error XDD pero gracias de todos modos