[c] String problem strstr()

Tasm-Devil

Erfahrenes Mitglied
Hallo Leute ich habe ein Problem. Und zwar kenne ich mich überhaupt nicht mit der string.h aus. Ich kann nich gescheid mit Strings vom Typ char * umgehen.
Nun habe ich folgendes Problem. Ich möchte aus einer html-datei alle E-Mail-adressen kopieren. Es soll ein ganz kleines Programm werden.
1. Suche nach "mailto:"
2. kopiere alles was danachkommt.
3. Höre bei ".de" auf zu kopieren.
(4. alles wird am ende aufgelistet)

so weit bin ich gekommen:

Code:
/* Datei laden*/
      iFileHandle = FileOpen("baden.txt", fmOpenRead);
      iFileLength = FileSeek(iFileHandle,0,2);
      FileSeek(iFileHandle,0,0);
      char *pszBuffer;
      pszBuffer = new char[iFileLength+1];
      iBytesRead = FileRead(iFileHandle, pszBuffer, iFileLength);
      FileClose(iFileHandle);
/* inhalt ist in pszBuffer gespeichert */
 
      char suchString1 []= "mailto:";
      char *tempString1;
      tempString1 = strstr (pszBuffer, suchString1)+7;
      char suchString2 []= ".de";
      char *tempString2;

ich weiß das ist nicht viel aber vieleicht kann mir ja einer helfen.
Danke.
 
Hi.

Bevor du den Rückgabewert der strstr Funktion verwendest mußt du auf jeden Fall erstmal überprüfen ob nicht NULL zurückgeliefert wurde.

C:
char* pos = strstr(pszBuf, "mailto:");
if (pos != NULL) {
  pos += strlen("mailto:");
  char* end = strstr(pos, ".de");
  if (end != NULL) {
    int len = end - pos + strlen(".de");
    char* dest = new char[len+1];
    strncpy(dest, pos, len);
    dest[len] = '\0';
    ...
    delete[] dest;
  }
}
Das Ganze mußt du dann natürlich in eine Schleife packen. Und nicht vergessen pszBuf mit delete[] freizugeben.

Gruß
 
Also vielen Dank erst mal. Das hat mich weiter gebracht. Aber jetzt tritt ein neues Problem auf. Und zwar ist die TLD nicht immer .de sondern auch .net oder .com

Hier ist mein bisheriger code
Code:
      iFileHandle = FileOpen("baden.txt", fmOpenRead);
      iFileLength = FileSeek(iFileHandle,0,2);
      FileSeek(iFileHandle,0,0);
      char *pszBuffer;
      pszBuffer = new char[iFileLength+1];
      iBytesRead = FileRead(iFileHandle, pszBuffer, iFileLength);
      FileClose(iFileHandle);
      char* pos;
      int counter = 0;
      AnsiString result[100]; // nur profesorisch, wird noch mithilfe von new verbessert
      do
      {
      pos = strstr(pszBuffer, "mailto:");
            if (pos != NULL)
            {
            pos += strlen("mailto:");
            pszBuffer = pos;
            char* end = strstr(pos, ".de");  //hier muss auch nach .net und .com geprüft warden
                  if (end != NULL)
                  {
                  int len = end - pos + strlen(".de");
                  char* dest = new char[len+1];
                  strncpy(dest, pos, len);
                  dest[len] = '\0';
                  result[counter++] = dest;
                  delete[] dest;
                  }
            }
      }
      while (pos != NULL);
 
      // now display it
      counter = 0;
      ListBox1->Clear();
      while (result[counter] != NULL) // fehler (counter schießt über das ende von result hinaus.
      {
      ListBox1->Items->Add(result[counter++]);
      }
 
Tasm-Devil hat gesagt.:
Also vielen Dank erst mal. Das hat mich weiter gebracht. Aber jetzt tritt ein neues Problem auf. Und zwar ist die TLD nicht immer .de sondern auch .net oder .com
Das ist natürlich schlecht mit deinem bisherigen Ansatz, weil vermutlich in jeder HTML .net .de bzw. .com drinsteht. Du müßtest halt schauen welches von den interessanten Endungen zuerst kommt.

So richtig wird das natürlich dann auch nicht funktionieren weil es noch viele andere Endungen gibt usw. Besser wäre natürlich das Dokument zu parsen und in href Attributen die mailto: Adressen auszulesen.

Tasm-Devil hat gesagt.:
Code:
            pszBuffer = pos;
Du darfst den Wert des Zeigers pszBuffer nicht überschreiben (wenn du ihn nicht nochmal irgendwo extra gesichert hast) weil du den Speicher ohne die Adresse sonst nicht mehr freigeben kannst. Das nennt man Speicherleck.

Du hast übrigens vergessen den Speicher mit delete[] freizugeben.

Gruß
 
so jetzt bin ich fertig.

Code:
void __fastcall TForm1::OpenBtnClick(TObject *Sender)
{
  if(OpenDialog1->Execute() == true)
  {
  iFileHandle = FileOpen(OpenDialog1->FileName, fmOpenRead);
  iFileLength = FileSeek(iFileHandle,0,2);
  FileSeek(iFileHandle,0,0);
  pszBuffer = new char[iFileLength+1];
  iBytesRead = FileRead(iFileHandle, pszBuffer, iFileLength);
  FileClose(iFileHandle);
  }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::searchBtnClick(TObject *Sender)
{
char* pos;
int counter = 0;
AnsiString result[100];
  do
  {
  pos = strstr(pszBuffer, "mailto:");
    if (pos != NULL)
    {
    pos += strlen("mailto:");
    pszBuffer = pos;
    char* end_de = strstr(pos, ".de");
    char* end_net = strstr(pos, ".net");
    char* end_com = strstr(pos, ".com");
      if (end_de != NULL || end_net != NULL || end_com != NULL)
      {
      int len = 0;
        if(end_de != NULL)
        len = end_de - pos + strlen(".de");
        if (len > 50 && end_net != NULL)
        len = end_net - pos + strlen(".net");
        if (len > 50 && end_com != NULL)
        len = end_com - pos + strlen(".com");
      char* dest = new char[len+1];
      strncpy(dest, pos, len);
      dest[len] = '\0';
      result[counter] = dest;
      counter++;
      delete[] dest;
      }
    }
  }
  while (pos != NULL);
delete[] pos;
delete[] pszBuffer;
// now display it
counter = 0;
Memo1->Clear();
  while (result[counter] != "")
  {
  Memo1->Lines->Add(result[counter]);
  counter++;
  }
  Label1->Caption = IntToStr(counter) + " E-Mail-adressen gefunden.";
}
//---------------------------------------------------------------------------
void __fastcall TForm1::SaveBtnClick(TObject *Sender)
{
  if(SaveDialog1->Execute() == true)
  Memo1->Lines->SaveToFile(SaveDialog1->FileName);
}
//---------------------------------------------------------------------------

danke nochmal
 
Zurück