• Sábado 18 de Mayo de 2024, 19:33

Autor Tema:  longitud de puntero a char  (Leído 4868 veces)

picyo

  • Visitante
longitud de puntero a char
« en: Miércoles 22 de Septiembre de 2010, 13:55 »
0
Hola, estoy probando como copiar cadenas de carácteres, de difereente forma. La forma mas interesante creo que es creando un puntero. Pero a la hora de dar longitud a este puntero, me aparece siempre 4, nunca lo que yo pretendo. Eso hace que al visualizar el contenido, solo vea las 4 primeras letras y luego una seria de simbolos:

Código: C++
  1.  
  2. #include <iostream>
  3. #include <string>
  4. using namespace std;
  5.  
  6. int  main(){
  7. int longitud,nElementos;
  8. char cadena[]="hola que tal";
  9. char cadena2[13];
  10.  
  11. int longitudArray=sizeof(cadena);;
  12. char *CadenaArray=new char[longitudArray];           // la hago de este modo, para poder copiar directamente el contenido de cadena a CAdenaArray
  13.  
  14.  
  15.  
  16. cout <<"variable longitudArray: "<<longitudArray<< endl;  
  17. cout <<"longitud de CADENA ARRAY: "<<sizeof(CadenaArray)<< endl; // AQUI EMPIEZA EL FALLO....¿¿ PQ ME DICE QUE ES 4, si la variable es de 12+1???
  18. cout <<"longitud de cadena: "<<sizeof(cadena)<< endl;
  19. cout <<"CADENA ARRAY: "<<*CadenaArray << endl;
  20. cout <<"CADENA ARRAY: "<<&CadenaArray << endl;
  21.  
  22. for (int z=0;z<sizeof(CadenaArray);z++){
  23. cout <<"CADENA ARRAY ( con for): "<<CadenaArray[z] << endl;
  24. }
  25. cout <<"CADENA ARRAY: "<<CadenaArray << endl;
  26.  
  27.  
  28. for(int q=0;q<=sizeof(cadena);q++){  // no deja directamente igualar dos cadenas de chars-solucionado arriba-
  29. cadena2[q]=cadena[q];
  30. }
  31.  
  32. cout << cadena<<"   ";
  33. cout << cadena2;
  34. nElementos = sizeof(cadena);
  35. cout << endl<< "NUMERO DE ELEMENTOS EN CADENA ES: " << nElementos << endl;
  36.  
  37. //cout << cadena[11];
  38. for ( unsigned int x=0; x<= nElementos; x++)
  39. {
  40.     if ( cadena[x]>='a' && cadena[x]<='z'){
  41.         cadena2[x]=cadena[x]-32;
  42.         cadena[x]=cadena[x]-32;
  43.         CadenaArray[x]=CadenaArray[x]-32;
  44.     }
  45. }
  46. cout << "En cadena2 hay : "<<endl<< cadena2<<endl;
  47. cout << "cadena hay "<<endl<< cadena<<endl;
  48. cout << "CadenaArray hay:  "<<endl<< CadenaArray<<endl;
  49. return 0;
  50. }
  51.  
  52.  
  53.  

Epa

  • Miembro MUY activo
  • ***
  • Mensajes: 242
  • Nacionalidad: ar
    • Ver Perfil
Re: longitud de puntero a char
« Respuesta #1 en: Miércoles 22 de Septiembre de 2010, 17:01 »
0
Buenas.

Es dificil explicar esto sin escribir un manual :P

Pero si queres entender por que pasa eso, busca info de como funciona el operador sizeof(), de punteros constantes, y de los diferentes lugares de almacenamiento de datos dentro de un programa (bloque de datos, stack y heap).

Pero para solucionar esto podes usar la funcion strlen()
O hacer tu propia funcion, teniendo en cuenta que todas las cadenas de caracteres llevan el caracter '' al final para identificar donde termina.

Para trabajar con arrays es mucho mas recomendable eso que usar sizeof.

Saludos
The sweet smell of a great sorrow lies over the land.


picyo

  • Visitante
Re: longitud de puntero a char
« Respuesta #2 en: Miércoles 22 de Septiembre de 2010, 17:27 »
0
mm si, una enciclopedia solo con eso :)
Bueno, he mirado ahora, y aseguro lo que si creía. El resultado de 4 es el resultado de la longitud del puntero. ASí lo entiendo vaya, que un puntero puede almacenar una direccion de 4 bytes.

Código: C++
  1.  
  2. #include <iostream>
  3. #include <string>
  4. using namespace std;
  5.  
  6. int  main(){
  7. int longitud,nElementos;
  8. char cadena[]="hola que tal";
  9. char cadena2[13];
  10. int longitudCadena=sizeof(cadena);
  11. int longitudArray=sizeof(cadena);
  12. char *CadenaArray=new char[longitudArray];
  13. for(int i=0; i<=longitudCadena;i++){  // PONGO LA VARIABLE longitud... PQ sizeof() ME DA EL TAMAÑO DE UN PUNTERO INT , SIEMPRE DE 4 BYTES.
  14.     CadenaArray[i]=cadena[i];
  15. }
  16. cout <<"variable longitudArray: "<<longitudArray<< endl;
  17. cout <<"longitud de CADENA ARRAY: "<<sizeof(CadenaArray)<< endl;
  18. cout <<"longitud de cadena: "<<sizeof(cadena)<< endl;
  19. cout <<"longitud de cadena2: "<<sizeof(cadena2)<< endl;
  20. cout <<"CADENA ARRAY: "<<*CadenaArray << endl;
  21. cout <<"CADENA ARRAY: "<<&CadenaArray << endl;
  22.  
  23. for (int z=0;z<longitudArray;z++){
  24. cout <<"CADENA ARRAY ( con for): "<<CadenaArray[z] <<endl;
  25. }
  26. cout <<"CADENA ARRAY: "<<CadenaArray << endl;
  27.  
  28.  
  29. for(int q=0;q<=sizeof(cadena);q++){  // no deja directamente igualar dos cadenas de chars-solucionado arriba-
  30. cadena2[q]=cadena[q];
  31. }
  32.  
  33. cout << cadena<<"   ";
  34. cout << cadena2;
  35.  
  36. cout << endl<< "NUMERO DE ELEMENTOS EN CADENA ES: " << longitudArray<< endl;
  37.  
  38. //cout << cadena[11];
  39. for ( unsigned int x=0; x<= longitudArray; x++)
  40. {
  41.     if ( cadena[x]>='a' && cadena[x]<='z'){
  42.         cadena2[x]=cadena[x]-32;
  43.         cadena[x]=cadena[x]-32;
  44.         CadenaArray[x]=CadenaArray[x]-32;
  45.     }
  46. }
  47. cout << "En cadena2 hay : "<<endl<< cadena2<<endl;
  48. cout << "cadena hay "<<endl<< cadena<<endl;
  49. cout << "CadenaArray hay:  "<<endl<< CadenaArray<<endl;
  50. return 0;
  51. }
  52.  
  53.  

Asi, cuando hago ahora los cout del final, veo lo que quiero ver, pero mi pretensión era simplemente copiar de un modo asi:
CadenaArray=cadena ( esto copiaría una direccion en otra, y al final los cout se ven mal los dos)
ó
*CadenaArray=cadena; ( pretendía que solo el contenido de CadenArray fuera lo de cadena) me daba fallo al compilar.

En efecto , quiero usar no se como aun..sizeof() y que me de el valor del contenido del puntero, y no el tamaño del  puntero en si
Realmente la copia la puedo hacer, y de hecho la he hecho, pero no exactamente como yo quiero, y sabiendo exactamente cómo lo hace

ProfesorX

  • Moderador
  • ******
  • Mensajes: 796
  • Nacionalidad: mx
    • Ver Perfil
Re: longitud de puntero a char
« Respuesta #3 en: Miércoles 22 de Septiembre de 2010, 19:49 »
0
Citar
En efecto , quiero usar no se como aun..sizeof() y que me de el valor del contenido del puntero, y no el tamaño del puntero en si

Eso nunca lo vas a lograr, aunque te des de topes con la pared.

Sucede que aunque los arreglos y los punteros estan relacionados, y en algunas ocasiones puedes intercambiar el uso de arreglos por el uso de punteros, NO son lo mismo.

Cuando defines un arreglo (en este caso un arreglo de char, pero esto es cierto para cualquier tipo de arreglo, sea int, float, etc), estas reservando una cantidad fija de memoria, que nunca va a cambiar.  O sea que cuando pones char[10] estas diciendo que el arreglo tendra 10 elementos, y eso nunca cambiara en el bloque en que lo hayas definido. Cuando tu colocas cadena[]="hola que tal", aunque no le hayas puesto explicitamente que el arreglo es de 13 caracteres, el compilador deduce automaticamente su tamaño, y no te dejara cambiarlo. Por lo tanto como es una cantidad fija de memoria asignada, sizeof() sabe cuanta memoria utiliza la variable, y te devuelve el tamaño del arreglo, pareciendo que fuera equivalente a strlen(), pero recuerda sizeof() devuelve el valor en bytes, si la cadena fuera de wide char (unicode) los caracteres unicode utilizan 2 bytes, por lo tanto sizeof devovelveria en este caso 25, que seria (12* 2) + 1. y por lo tanto no seria la longitud de la cadena.

Ahora si en lugar de utilizar un arreglo de char utilizas un apuntador a char, no estamos definiendo una cantidad fija de memoria como en el caso de un arreglo, en este caso no es posible saber donde termina, recuerda, los apuntadores solo guardan una direccion en la memoria, en este caso donde comienza el arreglo, pero no donde termina. Entences sizeof solo regresara el tamaño del apuntador. De hecho el tamaño del apuntador NO depende del tipo de variable al que apunta, sino del tamaño de las direcciones de memoria, entonces un apuntador a cualquier tipo de variable, sea char, float, int, etc. todas usaran 4 bytes, ya que en este caso las direcciones son de 4 bytes (o sistema de 32 bits), Cuando comiencen a utilizarse mas los sistemas de 64 bits, el tamaño de los apuntadores seran 8 bytes, y no 4 :)

Es debido a esta imposiblidad de saber donde termina un arreglo cuando se usan apuntadores, que se utiliza el caracter nulo para determinar el fin de la cadena. Internamente la funcion strlen verifica cuando llega al nulo, asi sabe su tamaño.

Esper con esto haberte aclarado la mente un poco respecto a arreglos y apuntadores.

Saludos :)
« última modificación: Miércoles 22 de Septiembre de 2010, 19:58 por ProfesorX »

NOTA:
==================================================================
Este foro es para ayudar, aprender, compartir... usenlo para eso,
NO SE RESUELVEN DUDAS POR MENSAJE PRIVADO Y MENOS POR CORREO
==================================================================

picyo

  • Visitante
Re: longitud de puntero a char
« Respuesta #4 en: Miércoles 22 de Septiembre de 2010, 19:56 »
0
uhmm y tanto, lo has explicado muy bien!
La verdad es que no me gusta definir los arrays con una longitud específica, me gusta eso que sean dinámicos ( también depende de la aplicación que les des, claro). En ese caso, siempre habré de usar apuntadores, y por lo que veo pues, nunca sizeof ( creía que size of hacia diferencias de tamaño en el tipo de apuntadores, esa reseña que no es asi, que es 4bytes -32bits- por el windows me ha abierto los ojos!!). usare la otra función que me has dicho pues. gracias!!