Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 06-08-2012
usuario87 usuario87 is offline
Miembro
NULL
 
Registrado: ago 2011
Posts: 10
Poder: 0
usuario87 Va por buen camino
¿como llenar de nulos una cadena?

hola , mi programa usa una funcion que esta dentro de una dll, esta funcion es parecida a GetSystemDirectory, se le pasa una direccion de memoria donde regresara una cadena que consta de caracteres distintos al caracter nulo (0) , pero al regresar de la funcion esta no te devuelve el numero de caracteres escritos en la direccion de memoria, en visual basic lo que se hace en estos casos es declarar una variable string y llenarlo de puros nulos y al regresar de la funcion simplemente busco el primer nulo dentro de la cadena y ese nulo me indica el final de esa cadena devuelta:

dim Cantidad as Integer
dim Buffer as string 'delcra la var string
Buffer = String(255,Chr(0)) 'asigna 255 nulos en la variable
ObtenerNombre Buffer 'Esta es la funcion que uso
Cantidad = InStr(1,Buffer,Chr(0)) ' aqui busco el primer caracter nulo que indica el final
Buffer = Mid(Buffer,1,Cantidad - 1) 'aqui cojo todos los caracteres -1 que seria el nulo
MsgBox Buffer 'muestro la cadena


¿como se haria eso en delphi?

intente usando setlength pero esta funcion no llena de nulos una cadena xP, para mi es mas facil usar una cadena.

Última edición por usuario87 fecha: 06-08-2012 a las 04:28:58.
Responder Con Cita
  #2  
Antiguo 06-08-2012
Avatar de Chris
[Chris] Chris is offline
Miembro Premium
 
Registrado: abr 2007
Ubicación: Jinotepe, Nicaragua
Posts: 1.678
Poder: 19
Chris Va por buen camino
Antes que todo, encuentro un poco confuso lo que dices. Pareciera como qué tu rutina en la DLL implementa las cadenas de C o algo similar. Desearía que aclararas un poco más tu próposito para darte una mejor ayuda.

Ahora, para llenar una cadena con nulos en Delphi, utiliza el siguiente código:
Código Delphi [-]
var
    Cadena: Array[0..255] of Char;
begin
    FillChar(Cadena, SizeOf(Cadena), 0);
end;

Vale la pena mencionar que las cadenas nativas de Delphi (String) no pueden estar llenas de Nulos, a menos que utilices cadenas con longitud específica, cómo por ejemplo: "cadena: string[255]". En el último caso, la variable cadena ya estará llena de nulos una vez creada.

Pero ya que utilizarás una función en una DLL, es mejor que utilices el código del primer ejemplo. Las cadenas nativas de Delphi no son buenas para interacturar con DLLs. Esto es porque por estándar, las DLLs trabajan con cadenas de C.

Saludos.
__________________
Perfil Github - @chrramirez - Delphi Blog - Blog Web
Responder Con Cita
  #3  
Antiguo 06-08-2012
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Empezado por Chris Ver Mensaje
Vale la pena mencionar que las cadenas nativas de Delphi (String) no pueden estar llenas de Nulos
¿A qué te refieres? Un string puede contener cualquier byte, incluido un 0 (nulo). La única restricción es que una tal cadena no se llevará bien con rutinas de texto.

// Saludos
Responder Con Cita
  #4  
Antiguo 06-08-2012
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.042
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Bienvenido a clubdelphi, usuario87, ¿ya leiste nuestra guía de estilo?, gracias por tu colaboración

Recuerda poner los tags al código fuente, ejemplo:



Gracias
Responder Con Cita
  #5  
Antiguo 09-08-2012
usuario87 usuario87 is offline
Miembro
NULL
 
Registrado: ago 2011
Posts: 10
Poder: 0
usuario87 Va por buen camino
Si, la rutina emplea cadenas de tipo C y como la rutina solo devuelve la cadena sin el nulo al final , entonces lo que se hace es poner una cadena llena de nulos y al regresar la rutina solo busco el primer nulo y ya se que hasta ahi es la cadena.
por poner un ejemplo la rutina puede regresar un nombre como "abcd", entonces regresara tal cual sin el nulo al final , esto en bytes seria 97-98-99-100, entonces si pongo la cadena en nulos antes de entrar en la rutina seria: 0-0-0-0-0-0-0 y al regresar seria 97-98-99-100-0-0-0 (lo que al mostrar seria abcd\0), especifico que tengo que usar cadenas porque es mucho mas facil porque la idea es llenar de nulos esa cadena para entrar en la rutina y luego del retorno usar la funcion Pos(Chr(0),Cadena) para buscar el nulo y asi encuentro el final.
Responder Con Cita
  #6  
Antiguo 09-08-2012
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Pues, tal como te indica Chris lo puedes hacer. El único problema sería si los datos devueltos ocupan más de 256 bytes.

// Saludos
Responder Con Cita
  #7  
Antiguo 09-08-2012
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.197
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Una función que trata cadenas al estilo C debe poner un nulo al final del Buffer que se le pasa, si no lo hace, entonces podemos decir que no es estilo C o que es una chapuza. Por lo tanto me inclino a pensar que si te devuelve un nulo final de cadena.

En el caso de que no devuelve el nulo, puedes usar un Buffer tipo array of char o un String con longitud asignada previamente o un ShortString si no va a ser mas larga de 255.

Para la llamada a esa función deberás usar un puntero que apunte al primer elemento de tu cadena o array:
En el caso de un array: @Buffer[0];
En el caso de un ShortString o String: @Cadena[1] (para luego poder asignar la longitud).

Si tienes que usar el resultado de la llamada como un String tienes estos casos:
En el caso de usar array of char puedes convertirlo a un String.
En el caso de usar un ShortString debes asignar al caracter[0] la longitud de la cadena sin el nulo final
En el caso de un String debes usar SetLength para asignar el tamaño sin el nulo final.



Saludos.

Última edición por escafandra fecha: 09-08-2012 a las 19:58:15.
Responder Con Cita
  #8  
Antiguo 09-08-2012
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
No creo que pueda usar un string sin conocer de antemano la longitud de la cadena devuelta. Dicho de otra forma, necesitaría usar SetLength antes de la llamada, de lo contrario no habría memoria asignada para recibir el resultado.

// Saludos
Responder Con Cita
  #9  
Antiguo 09-08-2012
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.197
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Cita:
Empezado por roman Ver Mensaje
No creo que pueda usar un string sin conocer de antemano la longitud de la cadena devuelta. Dicho de otra forma, necesitaría usar SetLength antes de la llamada, de lo contrario no habría memoria asignada para recibir el resultado.
Teniendo encuenta que va a usar una función de una dll parecida a GetSystemDirectory:
Cita:
Empezado por usuario87 Ver Mensaje
...mi programa usa una funcion que esta dentro de una dll, esta funcion es parecida a GetSystemDirectory...
El tamaño debe ser MAX_PATH. El problema del tamaño también lo tenemos en un buffer, y como ya dije antes debe asignarlo antes de usarlo:
Cita:
Empezado por escafandra Ver Mensaje
...puedes usar un Buffer tipo array of char o un String con longitud asignada previamente o un ShortString si no va a ser mas larga de 255...
Luego debes reasignar el tamaño del String al verdadero número de caracteres. En definitiva usas el String como un mero Buffer. Un ejemplo:
Código Delphi [-]
var
 S: String;
begin
 SetLength(S, 100);              // Asigno un tamaño
 lstrcpy(@S[1], 'Hola');         // API estilo C para copiar una cadena terminada en nulo 'Hola'#0
 S:= String(PAnsiChar(@S[1]));   // Reasigno el tamaño del String
end;

Saludos.
Responder Con Cita
  #10  
Antiguo 09-08-2012
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Es cierto que tienes que reasignar el tamaño también al regreso de la función. Pero sí usas un string, también tienes que ponerlo antes, así sea MAX_PATH. Si mandas el string, o @S[1] así nada más, obtendrás una violación de acceso.

// Saludos
Responder Con Cita
  #11  
Antiguo 09-08-2012
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.197
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Cita:
Empezado por roman Ver Mensaje
Es cierto que tienes que reasignar el tamaño también al regreso de la función. Pero sí usas un string, también tienes que ponerlo antes, así sea MAX_PATH. Si mandas el string, o @S[1] así nada más, obtendrás una violación de acceso.
Estamos de acuerdo.

Saludos.
Responder Con Cita
  #12  
Antiguo 10-08-2012
usuario87 usuario87 is offline
Miembro
NULL
 
Registrado: ago 2011
Posts: 10
Poder: 0
usuario87 Va por buen camino
jeje no pense que mi preguntilla iba a causar tantas respuestas, bueno miren primero el buffer debe estar si o si en nulos porque como ya dije la funcion de la dll solo me devuelve la cadena sin el nulo (una mala imitacion de las cadenas en C xP), segundo el buffer como maximo debe ser de 255 porque me va a devolver nombres y al principio en ese codigo de visual basic especifique "Buffer = String(255,Chr(0)) 'asigna 255 nulos en la variable" , queria hacerlo con cadenas porque me parecia mucho mas facil hacer algo como esto:

Código Delphi [-]
Var
  Buffer: string;
  Posicion: Byte;
begin
  Buffer:=LlenarNulos(255); // equivalente a Buffer = String(255,Chr(0))
  ObtenerNombres(PChar(Buffer));
  Posicion:=Pos(Chr(0),Buffer);
  Buffer:=Copy(Buffer,1,Posicion-1);
  Form1.Caption:='Tamaño de la cadena: '+IntToStr(Posicion-1);
  ShowMessage(Buffer);


usare shortstring y array of char, tambien se me habia ocurrido usar una api para asignar memoria y pasarle esa direccion a la funcion de la dll y luego busco el nulo mediante un puntero a esa direccion.
gracias
Responder Con Cita
  #13  
Antiguo 10-08-2012
usuario87 usuario87 is offline
Miembro
NULL
 
Registrado: ago 2011
Posts: 10
Poder: 0
usuario87 Va por buen camino
gracias .
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
como sumar con nulos? lledesma SQL 39 10-09-2008 19:28:17
como llenar la memoria Ram kurono Varios 11 10-09-2008 03:31:51
Como llenar con espacion en blanco o con ceros una cadena? Luis Alberto Varios 10 02-12-2005 19:14:02
Como Ingresar Valores En Blanco O Nulos En Access JanoRod Conexión con bases de datos 1 16-11-2005 15:40:48
S.O.S como selecciono campo nulos Ryu SQL 3 11-04-2005 16:40:50


La franja horaria es GMT +2. Ahora son las 02:44:41.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi