Club Builder - Foros de discusión Club Builder
Foro de C++Builder en español
 
 FAQFAQ   BuscarBuscar   MiembrosMiembros   Grupos de UsuariosGrupos de Usuarios   RegistrarseRegistrarse 
 PerfilPerfil   Entra para ver tus mensajes privadosEntra para ver tus mensajes privados   EntrarEntrar 

Buscar dentro de una cadena

 
Publicar nuevo tema   Responder al tema    Foros de discusión -> Consultas
Ver tema anterior :: Ver tema siguiente  
Autor Mensaje
Mensaje    Asunto: Buscar dentro de una cadena Responder citando

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
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

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

_________________
Cool
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email MSN Messenger
Mensaje    Asunto: Responder citando

Revisa también la función strtok

Saludos.
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

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
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Re: Buscar dentro de una cadena Responder citando

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
Ver perfil de usuario Enviar mensaje privado Enviar email
Mensaje    Asunto: Responder citando

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
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

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.
_________________
Cool
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email MSN Messenger
Mensaje    Asunto: Responder citando

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
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

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
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

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
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Ok, gracias! Lo he estado haciendo y todo bien.

Un saludo!
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mostrar mensajes de anteriores:   
Cambiar a:  
No puedes publicar temas nuevos en este foro
No puedes responder a temas en este foro
No puedes editar tus mensajes en este foro
No puedes borrar tus mensajes en este foro
No puedes votar en las encuestas de este foro


Hosting WordPress Indedmedia desde 3,99 €
© 2002–2026 Club Builder · Funciona con phpBB.