Programación General > C++ Builder

 ¿¿que Ocurre Con Text.c_str() De Un Tedit???

(1/3) > >>

garth:
en una rutina hago esto:

void __fastcall TForm3::bufferChange(TObject *Sender)
{
  buf=new char[buffer->MaxLength];

  buf=buffer->Text.c_str();
}

para tener en 'buf' lo que se ha introducido en el TEdit 'buffer'. Lo hace bien pero el ultimo caracter se lo come. Si MaxLength vale 5 y escribo "holas", buf va a contener: "hola".

Alguien me puede decir como arreglar esto. ¿Es un fallo del c++ builder o soy yo que soy un maleta?

Gracias.

FordFarlaine:
Bueno, esto esta un poco regular:
Primero, la memoria reservada con el operador 'new' no se libera automaticamente, la tienes que liberar con el operador 'delete', y aqui cada vez que ejecute la funcion haces una reserva de memoria que despues en algun sitio tendras que liberar. ¿Lo haces?
Segundo, suponiendo que despues la liberas en cualquier otro sitio, no estara bien de todas maneras ya que buf, entiendo que es un puntero a una cadena de caracteres, y primero reservas memoria para el y lo direccionas a esa reserva de memoria. Pero a continuacion lo vuelves a redireccionar a la direccion que te devuelve el operador c_str() de la clase AnsiString. Con lo que la memoria queda reservada pero inutilmente, ya que pierdes la direccion donde la tenias.

Soluciones:
 Primero, no se para que quieres el buffer auxiliar buf, pero si lo que quieres es tener una cadena de caracteres que en todo momento contenga lo que hay en el TEdit, ya la tienes en el propio control, y su direccion de memoria te la devuelve el operador c_str().

Si de todas maneras quieres tener en una variable (por algo que no logro entender), la direccion de lo que hay escrito. Entonces elimina la primera linea, no reservando memoria y limitandote a hacer la asignacion.

Y por ultimo, si quieres tener en otra cadena lo que en un momento dado habia escrito en el TEdit, tienes que hacer una copia de la memoria y no una asignacion de direccion. ¿Como? Asignas el valor NULL por defecto al puntero buf (por ejemplo en el oncreate del TEdit). Y aqui liberas el valor anterior del buf, y le reservas el nuevo valor para el tamaño que necesites, y acontinuacion haces una copia de memoria.

.
.
buf=NULL;
.
.

void __fastcall TForm3::bufferChange(TObject *Sender)
{
....
  if(buf!=NULL) delete [] buf;
  buf=new char[buffer->Text.Length()+1];   // el mas uno es para el caracter 0
                                                               // que termina el string
  memcpy(buf,buffer->Text.c_str(),buffer->Text.Length()+1); // copia la memoria
}

garth:
A ver FordFarlaine; me has abierto mucho los ojos. Si, soy un mulo programando. Te explico por encima a ver con que solucion me quedo:

Estoy haciendo un simulador del puerto PCI, y en buf quiero meter lo que el usuario escriba en el TEdit que va a ser lo que se "escriba" en la memoria reservada para un dispositivo pci. Por lo tanto lo quiero tener como un array de caracteres siempre accesible desde otro Form que es el que simula. buf lo tengo declarado como variable del Form. A 'buf' necesito acceder por posiciones y creo que con el ansistring del TEdit no obtengo solucion a lo que quiero no?

a ver si esto te lo ha aclarado.

Muchisimas gracias.

FordFarlaine:
Bueno, si te he entendido, el buf lo tienes declarado como variable miembro de la Form que utilizas como 'PCI', y no de la que tiene el TEdit.
Pues bien, si esto es así, yo elegiria una de las dos siguientes opciones:

Primera: la ultima que te dije en el otro post, pero colocando el buf=NULL, en el constructor de la Form 'PCI'. Teniendo en cuenta que tienes que hacer en el ".cpp" de la Form que contiene el TEdit un  #include con el ".h" de la form 'PCI' (cosa que me imagino ya hiciste).

Segunda: Si 'con acceder por posiciones' te refieres a poder acceder independientemente, a cada una de las letras del array. Puedes hacerlo desde la otra form, siempre que la Form que contiene el TEdit no este destruida, directamente con el TEdit, mediante dos maneras:
      1º- Con el famoso c_str(). esto de devuelve la direccion donde comienza el
            array de caracteres como si fuera 'Ansi C', asi el primer elemento lo
            obtienes con " (Form1->buffer->Text.c_str())[0] ", los demas
            sustituyendo el [0] por el elemento en cuestion.
      2º- Colocando el operador [] sobre el ansi string te devuelve directamente el
            caracter, ejemplo para el primer elemento " (Form1->buffer->Text)[1] "
            (notar que de una manera el primer elemento es el 0, y de la otra el 1)
   Para esta soluciontambien tendrias que #incluir en la Form 'PCI' el ".h" de la Form1, o como llames a la que contiene el TEdit

garth:
Muchas gracias Ford Farlaine! ;)

creo ke escogere la segunda. Ademas ya tenia #incluido :P el ".h" de los demas forms.

Una preguntita mas. Al simularlo, saco por pantalla el cronograma de estados por los que atraviesa el dispositivo PCI representando sus señales; eso lo hago utilizanfo el canvas. Ahora bien, cuando desplazo la barra de desplazamiento hacia la derecha para ver el resto de la simulacion, lo que se corre hacia la izquierda, se borra, desaparece. Hay alguna forma de refrescarlo para que no se pierda.

P.D.: yo he hecho a lo bruto que simulase de nuevo por medio de una funcion FormPaint en el evento OnPaint (el problema es que la simulacion no tiene por que ser la misma, intervienen variables "ramdom's").

Gracias por aguantarme. :D
Saludos.

Navegación

[0] Índice de Mensajes

[#] Página Siguiente

Ir a la versión completa