elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.
 
Inicio Ayuda Buscar Ingresar Registrarse
29 Mayo 2012, 01:10  


Tema destacado: Nueva página de elhacker.net en Google+ Google+

+  Foro de elhacker.net
|-+  Programación
| |-+  Programación Visual Basic (Moderadores: LeandroA, seba123neo, raul338)
| | |-+  obtener longitud de una cadena sin LEN
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: obtener longitud de una cadena sin LEN  (Leído 1,349 veces)
RHL


Desconectado Desconectado

Mensajes: 968


mental


Ver Perfil
obtener longitud de una cadena sin LEN
« en: 5 Septiembre 2011, 03:44 »

buenas tengo una duda señores
tengo este codigo:

Código
Dim A As String
Dim B As String
Dim dirA As Long
 
A = "prueba"
B = Space(1)
 
dirA = StrPtr(A)
 
 
CopyMemory ByVal B, ByVal dirA + 2, Len(dirA)
Debug.Print B
 
 
 

bien todo eso esta bien no ;D
mi duda es como puedo saber la longitud de una X cadena sin usar la funcion len? es posible eso? :P
ya que si uno no sabe cual es la longitud de una cadena ( el utlimo caracter ) no puedo saber hasta donde es el final de los caracteres de la cadena :P
bueno se le agradece ;D



En línea
BlackZeroX (Astaroth)
Wiki

Desconectado Desconectado

Mensajes: 2.831


I'Love...!¡.


Ver Perfil WWW
Re: obtener longitud de una cadena sin LEN
« Respuesta #1 en: 5 Septiembre 2011, 08:14 »

los strings en vb6 guardar antes del 1er caracter su longitud... es decir:

len() es equivale a leer la direccion en strptr(VariableString) - &H4

Dulces Lunas!¡.


« Última modificación: 5 Septiembre 2011, 19:34 por BlackZeroX▓▓▒▒░░ » En línea

Web Principal-->[ Blog(VB6) | Host File (Public & Private) | Scan Port | (New)MyInfraPC (Descubre mi Contraseña venefi. $) ]



The Dark Shadow is my passion.
El infierno es mi Hogar, mi novia es Lilith y el metal mi
RHL


Desconectado Desconectado

Mensajes: 968


mental


Ver Perfil
Re: obtener longitud de una cadena sin LEN
« Respuesta #2 en: 5 Septiembre 2011, 17:36 »

si lo ce tio el strptr me devuelve el puntero al primer caracter por eso tengo esa duda
si digamos en un bucle quiero obtener todos los caracteres

Código
dim cadena as string
dim Y as long
dim n as byte
dim X as string
 
cadena="HOLA MUNDO"
Y= strptr(cadena)
 
 
for n = 1 to [longitud]
copymemory byval X, byval Y,len(Y)
cadenaFinal = cadenafinal + X
Y = Y +2
next
 
bien con ese codigo creo que recorro cada uno de los caracteres pero como puedes ver necesito la longitud de la cadena porque sino el bucle se ejecutaria infinitamente o se saliera de la longitud de la cadena :P
es por eso que necesito saber la longitud, yo ce que puedo obtenerla con LEN pero existe otra forma? :P gracias ;D
« Última modificación: 5 Septiembre 2011, 17:39 por Raul100 » En línea
raul338
Moderador
***
Desconectado Desconectado

Mensajes: 2.371


La sonrisa es la mejor forma de afrontar las cosas


Ver Perfil WWW
Re: obtener longitud de una cadena sin LEN
« Respuesta #3 en: 5 Septiembre 2011, 19:08 »

Si, hasta que el carcater sea 0, o usa strLenA o strLenW :P
En línea

BlackZeroX (Astaroth)
Wiki

Desconectado Desconectado

Mensajes: 2.831


I'Love...!¡.


Ver Perfil WWW
Re: obtener longitud de una cadena sin LEN
« Respuesta #4 en: 5 Septiembre 2011, 19:22 »

mmm aqui te dejo el codigo que mas o menos te daba a entender anteriormente... igual puedes usar strLenW hay una variante llamada strLenA esa no te va a servir de mucho...

Código
Option Explicit
 
Private Declare Sub RtlMoveMemory Lib "kernel32" (ByVal pDst As Long, ByVal pSrc As Long, ByVal ByteLen As Long)
 
Private Sub Form_Load()
Dim sStr    As String   '   //  Apuntador...
   MsgBox altLen(sStr)
   sStr = "BlackZeroX"
   MsgBox altLen(sStr) & vbCrLf & Len(sStr)
 
   sStr = ""
   MsgBox altLen2(sStr)
   sStr = "BlackZeroX"
   MsgBox altLen2(sStr) & vbCrLf & Len(sStr)
 
End Sub
 
Public Function altLen(ByRef sStr As String) As Long
Dim lRet    As Long
   '   //  Simulacion de StrPtr()
   RtlMoveMemory VarPtr(lRet), VarPtr(sStr), &H4           '   //  Leemos el apuntardor a la cadena.
   If (lRet = &H0) Then Exit Function                      '   //  Si el puntero es &H0 es que no hay ninguna cadena.
   RtlMoveMemory VarPtr(lRet), ByVal (lRet - &H4), &H4     '   //  Leemos la longitud en Bytes SOLO de la cadena en UNICODE.
   altLen = (lRet \ 2)                                     '   //  Por ser UNICODE dividimos entre 2
End Function
 
 
Public Function altLen2(ByRef sStr As String) As Long
Dim lRet    As Long
   lRet = StrPtr(sStr)
   If (lRet = &H0) Then Exit Function                      '   //  Si el puntero es &H0 es que no hay ninguna cadena.
   RtlMoveMemory VarPtr(lRet), ByVal (lRet - &H4), &H4     '   //  Leemos la longitud en Bytes SOLO de la cadena en UNICODE.
   altLen2 = (lRet \ 2)                                    '   //  Por ser UNICODE dividimos entre 2
End Function
 
 

Y espero no equivocarme pero tambien se puede con readProcessMemory o igual RTLCopyMemory debes buscar  2 bytes nulos... esos indican el final de la cadena casi = que el Ansi donde es solo 1 Bytes Nulo el que indica el final...

Dulces Lunas!¡.
« Última modificación: 5 Septiembre 2011, 19:30 por BlackZeroX▓▓▒▒░░ » En línea

Web Principal-->[ Blog(VB6) | Host File (Public & Private) | Scan Port | (New)MyInfraPC (Descubre mi Contraseña venefi. $) ]



The Dark Shadow is my passion.
El infierno es mi Hogar, mi novia es Lilith y el metal mi
RHL


Desconectado Desconectado

Mensajes: 968


mental


Ver Perfil
Re: obtener longitud de una cadena sin LEN
« Respuesta #5 en: 6 Septiembre 2011, 04:27 »

sale gracias no se me habia ocurrido eso de si es NULL ;D

@BlackZeroX

hey tio me puedes explicar la primera alternativa :P casi noentiendo :P
bueno mi logica me dice esto: :xD
en la llamada a ala rtlmovememory, en el segundo parametro usas la funcion varptr() con esa funcion se obtiene la direccion del cadena de bufer completa no? a diferencia de la strptr que devuelve la direccion del primer caracter a la cadena no? :P
en tonces si obtienes la direccion del bufer veo que pasas la direccion a la direccion de una variable :P
mi logica me dice que haces una asignacion de direccion :P , no entiendo :P
es como esto:

A* = B* ( en C++ quiza me se explicar mejor :P )

y pues arriba escribes simulacion de strptr :P
En línea
BlackZeroX (Astaroth)
Wiki

Desconectado Desconectado

Mensajes: 2.831


I'Love...!¡.


Ver Perfil WWW
Re: obtener longitud de una cadena sin LEN
« Respuesta #6 en: 6 Septiembre 2011, 08:11 »

.
Me ire un poco a algo mas interno en vb6, esperando no confundir a nadie... para que comprendan un poco mas la estructra de las variables en VB6 y por ende comprener algunos aspecto y entender unos trucos avanzados con respecto a velocidad en vb6.

Definicion Basica Fundamental.
Puntero o Apuntador: Es una variable que contiene la dirrecion de otra variable.

Guiandome en esta DEFINICION que es irrefutable puedo AFIRMAR y SUSTENTAR LO SIGUIENTE.

Cuando declaras una variable tipo String, Array del tipo que sea y ademas NO TIENE UNA LONGITUD FIJA, se pueden y deben considerarse como APUNTADORES, en vb6 NO HAY PUNTEROS DE MANEJO LIBRE es decir que no podemos declarar y modificar a gusto los punteros de manera deliberada como en C/C++ PERO SE PUEDEN SIMULAR asiendo algunas cosillas, aun asi no le quitara el hecho de que es CUTRE pero FUNCIONAL y es mas puede acercarse un poco a la velocidad de C/C++ pero no la igualara ni superara en ningun momento.

En el caso de C/C++ con respecto a los APUNTADORES que solo le pones el "*" y obtienes el contenido de donde apunte, en VB6 DEBES usar RtlMoveMemory para SIMULAR LA RUTINA DE C/C++ (*) respecto a un APUNTADOR.

En C seria... algo asi no llendo a mas lios...

Código
 
char a[] = "BlackZeroX";
char* pa = a;  // Se guarda el puntero de la variable "a" en "pa".
 
 

En VB6 se hace asi para SIMULAR lo anterior para saltarnos la restriccion que nos pone vb6.

Código
 
Dim a as string
Dim b as string
 
a = "BlackZeroX"
RtlMoveMemory VarPtr(b), VarPtr(a), &H4 ' // Lo mismo que lo anterior en C/C++...
' // Antes de terminar el proceso donde se Autodestruyen ambas variables hay que hacer esto:
RtlMoveMemory VarPtr(b), &H0 &H4 ' // esta seria otra desventaja ya que SI NO SE HACE PROVOCA A LA LARGA UN CRASH.
' // Nota: si "b" apuntaba a un contenido o ya se le habia asignado un contenido X debera de guardarse la _
dirrecion ala que apuntaba en una variable tipo long, y al final antes de su autodestruccion debera de volver _
a tener el mismo puntero, ya que de lo contrario se crearia un Extraordinario Memory leak (Fuga de memoria) _
y al final un Crash...

 

Caso omiso cuando se declara.

Código
 
Dim a as string * 20
 
 

La variable "a" no apunta a ningun lugar, ya que su memoria ya esta asignada y es CONSTANTE (Su longitud)


En resumen en C/C++ para obtener la longitud de una cadena en VB6 debes hacer esto:

Código
 
lLn = ((int*)(pSringVB6 - 0x4))
// pSringVB6 es el puntero a la variable string de vb6 obtenida con StrPtr
if (lLn) lLn >>= 1;
/*
Dividimos entre 2 de manera binaria SOLO si se paso con StrPtr() el puntero
de la string de lo contrario No debera ser dividido entre 2 ya que vb6 transforma
una variable String en formato Ansi... es decir quita los Bytes Nulos que sirven
como separadores en el formato Unicode de vb6 aun que no se ocupen para eso.
*/

 
 

Ejemplo y codigo en C (dll) + vb6 <click aquí>, Recomendacion Comilador Codeblocks.

En vb6 SIN USAR LEN, LENB, Apis o similares...

Código
 
Public Function altLen(ByRef sStr As String) As Long
Dim lRet    As Long
   '   //  Simulacion de StrPtr()
   RtlMoveMemory VarPtr(lRet), VarPtr(sStr), &H4           '   //  Leemos el apuntardor a la cadena.
   If (lRet = &H0) Then Exit Function                      '   //  Si el puntero es &H0 es que no hay ninguna cadena.
   RtlMoveMemory VarPtr(lRet), ByVal (lRet - &H4), &H4     '   //  Leemos la longitud en Bytes SOLO de la cadena en UNICODE.
   altLen = (lRet \ 2)                                     '   //  Por ser UNICODE dividimos entre 2
End Function
 
 
Public Function altLen2(ByRef sStr As String) As Long
Dim lRet    As Long
   lRet = StrPtr(sStr)
   If (lRet = &H0) Then Exit Function                      '   //  Si el puntero es &H0 es que no hay ninguna cadena.
   RtlMoveMemory VarPtr(lRet), ByVal (lRet - &H4), &H4     '   //  Leemos la longitud en Bytes SOLO de la cadena en UNICODE.
   altLen2 = (lRet \ 2)                                    '   //  Por ser UNICODE dividimos entre 2
End Function
 
 

Nota: Duando se declara una variable tipo Array sea cual sea en lugar de apuntar a su primer indice, realmente apunta a su Estructura SafeArray y en esta su miembro pvData apunta a su primer elemento... cabe destacar que si es un array String quiere decir que su elemento al que apunta pvData seran apuntadores ya que no tienen una longitud Definida.

Temibles Lunas!¡.
« Última modificación: 6 Septiembre 2011, 08:48 por BlackZeroX▓▓▒▒░░ » En línea

Web Principal-->[ Blog(VB6) | Host File (Public & Private) | Scan Port | (New)MyInfraPC (Descubre mi Contraseña venefi. $) ]



The Dark Shadow is my passion.
El infierno es mi Hogar, mi novia es Lilith y el metal mi
RHL


Desconectado Desconectado

Mensajes: 968


mental


Ver Perfil
Re: obtener longitud de una cadena sin LEN
« Respuesta #7 en: 6 Septiembre 2011, 19:17 »

buenas ;D bueno primeramente tio gracias por tomarte el tiempo por explicar ya estoy estudiando bien detallado tu expicacion ahora tengo una duda :P noce si te falto escribir el "byval" en el uso de la API :P
aparte que teste los codigos y no me paso lo que habia en las variables :P
o me equivoco y RtlMoveMemory pasa ya con Byval? :P a diferencia de CopyMemory como te escribi en MP no encontre la declaracion de RtlMemory :P o es la misma con CopyMemory y en la declaracion escribes RtlMoveMemory... :P
En línea
BlackZeroX (Astaroth)
Wiki

Desconectado Desconectado

Mensajes: 2.831


I'Love...!¡.


Ver Perfil WWW
Re: obtener longitud de una cadena sin LEN
« Respuesta #8 en: 6 Septiembre 2011, 19:37 »

@Raul100

Para que la buscas en google si ya te la deje aqui dicha declaracion API unos post mas arribita, y si es la misma solo que el alias o nombre de la funcion REAL es RtlMoveMemory pero se conoce mas comunmente como CopyMemory...

El byval si se pone en los parametros de la declaracion API entonces PUDE no escribirse en las llamadas, de lo contrario si no esta el byval en algun parametro de la declaracion API tendria que declararse byval si no se quiere pasar una variable por referencia, ten en cienta que si no se escribe byval se toma como referencia cada parametro.

Un ejemplo MUY ENTENDIBLE y aplicable a las APIS...

Código
 
Option Explicit
 
Private Sub Form_Load()
Dim sStr    As String
   sStr = "Hola Mundo"
   MsgBox aaa(sStr)
   MsgBox sStr
 
   sStr = "Hola Mundo"
   MsgBox bbb(sStr)
   MsgBox sStr
End Sub
 
Public Function aaa(valor As String) As String
   valor = "BlackZeroX"
   aaa = valor
End Function
 
Public Function bbb(ByVal valor As String) As String
   valor = "BlackZeroX"
   bbb = valor
End Function
 
 

Nota: Cuando es una funcion/proceso hecho en vb6 como los del ejemplo anterior no se deberia poner byval en las llamadas, solo es valido para APIS.

Dulces Lunas!¡.
« Última modificación: 6 Septiembre 2011, 19:45 por BlackZeroX▓▓▒▒░░ » En línea

Web Principal-->[ Blog(VB6) | Host File (Public & Private) | Scan Port | (New)MyInfraPC (Descubre mi Contraseña venefi. $) ]



The Dark Shadow is my passion.
El infierno es mi Hogar, mi novia es Lilith y el metal mi
RHL


Desconectado Desconectado

Mensajes: 968


mental


Ver Perfil
Re: obtener longitud de una cadena sin LEN
« Respuesta #9 en: 7 Septiembre 2011, 00:59 »

 :D ya entendi todo :D gracias tio (Y)
perdon por casi explicarlo con manzanas :xD
En línea
LeandroA
Moderador
***
Desconectado Desconectado

Mensajes: 693


Seguime


Ver Perfil WWW
Re: obtener longitud de una cadena sin LEN
« Respuesta #10 en: 7 Septiembre 2011, 11:37 »

Hola otra opcion con apis


Código:
Option Explicit
Private Declare Function lstrlenW Lib "kernel32" (ByVal lpString As Long) As Long
Private Sub Form_Load()
    Dim s As String
    s = "Hola mundo"
    MsgBox lstrlenW(StrPtr(s))
End Sub

EDIT:  ahora que recuerdo si dentro de la cadena tenes un Nullchar chr(0) solo te cuenta hasta esa posición
« Última modificación: 7 Septiembre 2011, 19:06 por LeandroA » En línea

Psyke1
Wiki

Desconectado Desconectado

Mensajes: 1.005



Ver Perfil WWW
Re: obtener longitud de una cadena sin LEN
« Respuesta #11 en: 10 Septiembre 2011, 02:24 »

La forma más rápida que sé de hacerlo es esta:
Código
Option Explicit
 
Private Sub Form_Load()
Dim s$
   s = "Hola mundo"
   MsgBox LenB(s) \ 2
End Sub

La función LenB() te devuelve la longitud en Bytes de una cadena, después dividimos entre dos y ya está. :rolleyes:
Los test que hice cuando programaba me dieron esta conclusión en cuanto a rapidez se refiere:
Código:
Lenb\2 > Len() > lstrlenW()


@BlackZeroX▓▓▒▒░░: Dios mío, había olvidado la dedicación que pones en tus explicaciones. :D

DoEvents! :P
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
[batch] Funcion :len (devuelve la longitud de una cadena)
Scripting
The Shadow 0 518 Último mensaje 18 Febrero 2008, 21:32
por The Shadow
Obtener caracteres de una Cadena VB.NET
.NET
Xhushito 7 5,426 Último mensaje 29 Diciembre 2009, 02:06
por Xhushito
Longitud de una cadena en mssql_fetch_object
PHP
Belem 1 973 Último mensaje 19 Abril 2010, 16:42
por MazarD
[Batch] 6 maneras de saber la longitud de una cadena
Scripting
modubat 1 1,361 Último mensaje 21 Septiembre 2010, 22:05
por xassiz~
[C] ¿Por que una cadena acepta mas valores que su longitud? (solucionado)
Programación C/C++
xiruko 8 450 Último mensaje 19 Abril 2012, 06:06
por david_BS
Powered by SMF 1.1.16 | SMF © 2006-2008, Simple Machines