| Ver tema anterior :: Ver tema siguiente |
| Autor |
Mensaje |
zankiu Lt Cmdr

Registrado: 23 Ene 2008Mensajes: 106
|
Publicado: Mie 17 Sep, 2008 5:51 pm Asunto: Buscar dentro de una cadena |
|
|
Hola.
Tengo una pequeña duda, tengo definido:
| Código: | String cadena = unaCadenaIp; |
la variable unaCadenaIp tiene la forma XXX.XXX.XXX.ZZZ que corresponde a la forma de una dirección IP.
Busco algo que pueda cambiar la última parte de la IP, es decir la parte de ZZZ.
Para esto estoy probando con:
| Código: | int num = cadena.Pos("."); |
entonces num devuelve 4 ya que el primer "." está en la cuarta posición, pero ¿cómo sigo recorriendo en la cadena para que me lea hasta la posición del tercer punto y me devuelva en num el valor de la posición del tercer punto?
Gracias. |
|
| Volver arriba |
|
 |
Cesar C. Salazar Gonzalez Master


Registrado: 01 Oct 2002Mensajes: 2155Ubicación: San Cristóbal de Las Casas, Chiapas
|
Publicado: Mie 17 Sep, 2008 9:20 pm Asunto: |
|
|
Te sirve una funcion para dividir cadenas a partir de un caracter?
| Código: | //*******************funicion que divide una cadena a partir de un caracter ****
TStrings *__fastcall DivideCadena(AnsiString ctmp, AnsiString LetraDivisora)
{
TStringList *ArregloCadena = new TStringList();
int pos=ctmp.Pos(LetraDivisora);
if(pos!=0){
ArregloCadena->Add(ctmp.SubString(1,pos-1));
ctmp=ctmp.SubString(pos+1,ctmp.Length());
pos=ctmp.Pos(LetraDivisora);
while (pos!=0)
{
Application->ProcessMessages();
if (pos!=0)
{
ArregloCadena->Add(ctmp.SubString(1,pos-1));
ctmp=ctmp.SubString(pos+1,ctmp.Length());
}
pos=ctmp.Pos(LetraDivisora);
}
ArregloCadena->Add(ctmp.SubString(1,ctmp.Length()));
}else{
ArregloCadena->Add(ctmp);
}
return (ArregloCadena);
} |
y la manera de usarse según tu ejemplo es.
| Código: | String cadena = unaCadenaIp;
TStrings *cadDividida = DivideCadena(cadena,".");
cadDividida->Strings[0]; //xxx
cadDividida->Strings[1]; //xxx
cadDividida->Strings[2]; //xxx
cadDividida->Strings[3]; //zzz
|
_________________
 |
|
| Volver arriba |
|
 |
escafandra Master

Registrado: 29 Nov 2007Mensajes: 625Ubicación: Madrid - España
|
Publicado: Mie 17 Sep, 2008 10:49 pm Asunto: |
|
|
Revisa también la función strtok
Saludos. |
|
| Volver arriba |
|
 |
escafandra Master

Registrado: 29 Nov 2007Mensajes: 625Ubicación: Madrid - España
|
Publicado: Jue 18 Sep, 2008 12:11 am Asunto: |
|
|
También puedes tener en cuenta esto:
| Código: |
String A= "xxx.ccc.vvv.bbb";
int n = (int)strrchr(A.c_str(), '.')-(int)A.c_str()+1; // n es el indice del elemento bbb (apunta a la primera b) si el primer caracter da A se considera el 0
|
O con punteros:
| Código: | char *C = strrchr(A.c_str(), '.')+1 // puntero a la cadena "bbb" |
Saludos. |
|
| Volver arriba |
|
 |
Angel Master


Registrado: 15 Abr 2003Mensajes: 2311Ubicación: Toledo (España)
|
Publicado: Jue 18 Sep, 2008 9:32 am Asunto: Re: Buscar dentro de una cadena |
|
|
| zankiu escribió: | entonces num devuelve 4 ya que el primer "." está en la cuarta posición, pero ¿cómo sigo recorriendo en la cadena para que me lea hasta la posición del tercer punto y me devuelva en num el valor de la posición del tercer punto?
Gracias. |
Simplemente: Utiliza la función LastDelimiter. Y si quieres cambiar el trozo final puedes hacerlo así:
| Código: | AnsiString cCadenaEnt, cCadenaSal;
cCadenaEnt = "XXX.XXX.XXX.ZZZ";
cCadenaSal = cCadenaEnt.SubString(1, cCadenaEnt.LastDelimiter(".")) + "YYY"; |
Al ejecutarlo convertirá XXX.XXX.XXX.ZZZ en XXX.XXX.XXX.YYY y, además, le da lo mismo que las direcciones IP sea de 1, 2 ó 3 posiciones. _________________ Un saludo
Necesitamos tu ayuda: Envía AI al 27595 (Coste 1,20 euros + IVA) |
|
| Volver arriba |
|
 |
zankiu Lt Cmdr

Registrado: 23 Ene 2008Mensajes: 106
|
Publicado: Jue 18 Sep, 2008 6:06 pm Asunto: |
|
|
Hola!
Ante todo gracias por la pronta respuesta.
He conseguido esto, que me funciona:
Lo tengo en un unit.cpp que está asociado a un form llamado MainForm.
| Código: | void __fastcall TMainForm::SpeedButton1Click(TObject *Sender)
{
int nIP;
cadIP = cap2->GetIp_host(); //esto me da el valor de la IP de mi pc
for (nIP = 1; nIP < 256; nIP ++)
{
cadRangoIP = cadIP.SubString(1, cadIP.LastDelimiter(".")) + AnsiString(nIP);
PaqueteICMP->Host=cadRangoIP;
PaqueteICMP->Ping();
//this->Memo1->Lines->Add(cadRangoIP);
}
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::PaqueteICMPReply(TComponent *ASender,
const TReplyStatus &AReplyStatus)
{
AnsiString result[5];
String info, estado;
result[3] = IntToStr((int)AReplyStatus.TimeToLive);
//Comprobación de si hay ping mediante el TTL, si TTL = 0 => no hay //ping
if (result[3] == 0)
{
info="no hay ping";
estado = "OFF";
}
else
{
//info="Ping desde: "+result[1]+ ", tiempo de respuesta: "+result[4]+" "+result[5];
info = "hay ping";
estado = "ON";
}
//salida de datos por el memo
this->Memo1->Lines->Add(cadRangoIP + "->" + info);
//salida de datos por un listview, esto se me cuelga
TListItem* item = MainForm->ListView1->Items->Add();
item = MainForm->ListView1->Items->Add();
item->Caption = estado;
item->SubItems->Add(cadRangoIP);
item->SubItems->Add(info);
}
|
Esto me funciona bien si comento las lineas referidas al listview, pero cuando quiero sacar los datos por un listview se me cuelga.
Entonces he pensado en pasarlo a un Thread... pero no lo tengo claro ya que no se cómo pasar la función
| Código: | void __fastcall TMainForm::PaqueteICMPReply(TComponent *ASender,
const TReplyStatus &AReplyStatus) |
a otro unit...
he intentado esto en el FindRangoIP.cpp que es el .cpp del thread
| Código: | __fastcall FindRangoIP::FindRangoIP(bool CreateSuspended)
: TThread(CreateSuspended)
{
}
//---------------------------------------------------------------------------
void __fastcall FindRangoIP::Execute()
{
int nIP;
AnsiString cadIP_, cadRangoIP;
cadIP_ = MainForm->cadIP;
for (nIP = 1; nIP < 4; nIP ++)
{
cadRangoIP = cadIP_.SubString(1, cadIP_.LastDelimiter(".")) + AnsiString(nIP);
MainForm->PaqueteICMP->Host=cadRangoIP;
MainForm->PaqueteICMP->Ping();
//this->Memo1->Lines->Add(cadRangoIP);
}
}
//---------------------------------------------------------------------------
void __fastcall FindRangoIP::PaqueteICMPReply(TComponent *ASender,
const TReplyStatus &AReplyStatus)
{
AnsiString result[5];
String info, estado;
result[3] = IntToStr((int)AReplyStatus.TimeToLive);
//Comprobación de si hay ping mediante el TTL, si TTL = 0 => no hay ping
if (result[3] == 0)
{
info="no hay ping";
estado = "OFF";
}
else
{
//info="Ping desde: "+result[1]+ ", tiempo de respuesta: "+result[4]+" "+result[5];
info = "hay ping";
estado = "ON";
}
//this->Memo1->Lines->Add(cadRangoIP + "->" + info);
TListItem* item = MainForm->ListView1->Items->Add();
item = MainForm->ListView1->Items->Add();
item->Caption = estado;
item->SubItems->Add(cadRangoIP);
item->SubItems->Add(info);
} |
y en el FindRangoIP.h tengo:
| Código: | ...
public:
_fastcall FindRangoIP(bool CreateSuspended);
void __fastcall PaqueteICMPReply(TComponent *ASender,const TReplyStatus &AReplyStatus); |
pero al compilar me da error diciéndo que:
[C++ Error] uThHostAlive.h(15): E2293 ) expected
[C++ Error] uThHostAlive.cpp(47): E2316 '_fastcall FindRangoIP::PaqueteICMPReply(TComponent *,const TReplyStatus &)' is not a member of 'FindRangoIP'
ambos son de la función PaqueteICMPReply uno en el .cpp y otro en el .h.
¿Cómo puedo hacerlo funcionar? ¿Quizás haya otra forma de comprobar que haya o no ping que no sea mediante el evento OnReply?
Gracias. |
|
| Volver arriba |
|
 |
Cesar C. Salazar Gonzalez Master


Registrado: 01 Oct 2002Mensajes: 2155Ubicación: San Cristóbal de Las Casas, Chiapas
|
Publicado: Jue 18 Sep, 2008 6:25 pm Asunto: |
|
|
Antes que empieces a gestionar tus direcciones, quiero comentarte algo
xxx.yyy.zzz.1 no es lo mismo que
xxx.yyy.zzz.01 que tampoco es lo mismo que
xxx.yyy.zzz.001 aqui estamos hablando de 3 segmentos diferentes de red
verifica bien tus rangos de direcciones.
los navegadores pueden componer las 3 ultimas referencias, pero no asi un ping.
Saludos. _________________
 |
|
| Volver arriba |
|
 |
escafandra Master

Registrado: 29 Nov 2007Mensajes: 625Ubicación: Madrid - España
|
Publicado: Jue 18 Sep, 2008 9:40 pm Asunto: |
|
|
| Cita: | //salida de datos por un listview, esto se me cuelga
TListItem* item = MainForm->ListView1->Items->Add();
item = MainForm->ListView1->Items->Add();
item->Caption = estado;
item->SubItems->Add(cadRangoIP);
item->SubItems->Add(info);
|
No debería colgarse, sólo que te sobra una asignación de item, es decir:
| Código: | TListItem* item = MainForm->ListView1->Items->Add();
item->Caption = estado;
item->SubItems->Add(cadRangoIP);
item->SubItems->Add(info);
|
Saludos. |
|
| Volver arriba |
|
 |
zankiu Lt Cmdr

Registrado: 23 Ene 2008Mensajes: 106
|
Publicado: Vie 19 Sep, 2008 2:46 pm Asunto: |
|
|
| Cita: |
No debería colgarse, sólo que te sobra una asignación de item, es decir:
TListItem* item = MainForm->ListView1->Items->Add();
item->Caption = estado;
item->SubItems->Add(cadRangoIP);
item->SubItems->Add(info);
|
Cierto, me sobra una asignación de item, se me pasó al copiarlo en el foro, pero en mi código está correcto.
Pero sí que se me cuelga al hacer un for a 255 elementos y que se vaya haciendo un add() en el listview.
De todas maneras si quiero pasar a un objeto Thread y ejecutarlo en un hilo este trozo de código:
| Código: |
void __fastcall TMainForm::SpeedButton1Click(TObject *Sender)
{
int nIP;
cadIP = cap2->GetIp_host(); //esto me da el valor de la IP de mi pc
for (nIP = 1; nIP < 256; nIP ++)
{
cadRangoIP = cadIP.SubString(1, cadIP.LastDelimiter(".")) + AnsiString(nIP);
PaqueteICMP->Host=cadRangoIP;
PaqueteICMP->Ping();
//this->Memo1->Lines->Add(cadRangoIP);
}
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::PaqueteICMPReply(TComponent *ASender,
const TReplyStatus &AReplyStatus)
{
AnsiString result[5];
String info, estado;
result[3] = IntToStr((int)AReplyStatus.TimeToLive);
//Comprobación de si hay ping mediante el TTL, si TTL = 0 => no hay //ping
if (result[3] == 0)
{
info="no hay ping";
estado = "OFF";
}
else
{
//info="Ping desde: "+result[1]+ ", tiempo de respuesta: "+result[4]+" "+result[5];
info = "hay ping";
estado = "ON";
}
//salida de datos por el memo
this->Memo1->Lines->Add(cadRangoIP + "->" + info);
//salida de datos por un listview, esto se me cuelga
TListItem* item = MainForm->ListView1->Items->Add();
item->Caption = estado;
item->SubItems->Add(cadRangoIP);
item->SubItems->Add(info);
} |
¿cómo lo podría hacer? ya que no tengo muy claro cómo poder pasar este evento:
| Código: | void __fastcall TMainForm::PaqueteICMPReply(TComponent *ASender,
const TReplyStatus &AReplyStatus) |
a un nuevo *.cpp
Espero haberme explicado bien.
Gracias |
|
| Volver arriba |
|
 |
escafandra Master

Registrado: 29 Nov 2007Mensajes: 625Ubicación: Madrid - España
|
Publicado: Sab 20 Sep, 2008 10:23 am Asunto: |
|
|
Mira la ayuda del Builder "TThread".
Crea una clase TThread. En la función Execute debes meter tu código.
Normalmente se hace dentro de un bucle que detecte que el valor de la Variable Terminated sea true para terminar tu hilo.
El código que metas no debe ser el evento en si sino el código que ese evento ejecute.
Ten en cuenta que no puedes utilizar directamente las VCL de tu Form1 desde el hilo, para ello esta la función Synchronize.
En el lugar donde quieres que se ejecute tu hilo:
| Código: | MiThread *hilo = new MiThread (false); // creas y ejecutas tu hilo de un tirón |
o tambien:
| Código: | MiThread *hilo = new MiThread (true); // creas tu hilo suspendido
.
.
.
hilo->Resume(); // Ejecutas tu hilo
|
Saludos. |
|
| Volver arriba |
|
 |
zankiu Lt Cmdr

Registrado: 23 Ene 2008Mensajes: 106
|
Publicado: Lun 22 Sep, 2008 12:05 pm Asunto: |
|
|
Ok, gracias! Lo he estado haciendo y todo bien.
Un saludo! |
|
| Volver arriba |
|
 |
|