# [C++] Datei durchsuchen



## proBier (14. Juli 2003)

C++ Datei durchsuchen

Ich möchte eine Datei nach einem Schlüsselwort durchsuchen. Also Eingabe: Schlüsselwort; Ausgabe: ja, falls Schlüsselwort gefunden; nein, sonst.

Ich wollte dazu wie folgt vorgehen: Den Inhalt der Datei in einen String einlesen, und dann den String nach dem Schlüsselwort durchsuchen.

Da ich aber absoluter C++-Anfänger bin, hab ich schon beim Einlesen der Datei in den String meine Mühe. Deshalb meine Frage: Wie kann ich das realisieren? Gibt es evtl. eine vordefinierte Funktion/Methode den String zu finden?

Das ganze versuch ich mit MFC zu realisieren.

Ich bin für jeden Rat dankbar!


----------



## Vaethischist (15. Juli 2003)

*CStdioFile* ist die Klasse, die Du brauchst. Insbesondere *ReadString()* wird Dich dabei interessieren. Dann kannst Du den eingelesenen CString einfach per *Find()* (aus der CString-Klasse) nach dem Schlüsselwort durchsuchen.


----------



## proBier (16. Juli 2003)

Erstmal Danke für die Antwort!

Ich hab es mal ausprobiert, schaffe es aber immer noch nicht den Inhalt der Datei in einen String zu laden.
Zum test hab ich mal folgendes geschrieben:

CStdioFile csFile;
csFile.Open("datei.txt",CFile::modeRead | CFile::typeText);
CString str = "";

char buf[100];
while (csFile.ReadString( buf, 99 )) {
  cout << buf;
}

Hier wird der Dateiinhalt auf der Console ausgegeben. Aber wie schaffe ich es den Inhalt nicht an die Konsole sondern den CString str weiterzuleiten.

Dann hab ich noch folgende while-Schleife probiert:
while (csFile.ReadString( str )) {
  cout << *str;
}
Hier wird allerdings nur der erste Buchstabe einer Zeile übergeben und nicht die ganze Zeile.

Wie kann ich einen String mit dem inhalt einer Textdatei füllen?


----------



## bitmaster (16. Juli 2003)

Ich code zwar nicht mit der MFC, aber das mit dem ersten Zeichen
kann ich dir schon erklären:

C++ zählt von 0 auf, und da dann warscheindlich der default-Wert 0 ist, nimmt er immer das erste Zeichen.
Falls du es nicht mit der MFC schaffst, kannst dus mir ja sagen.


----------



## proBier (16. Juli 2003)

ich probier schon den ganzen nachmittag und krieg es einfach nicht gebacken. wie gesagt ich bin totaler c++ anfänger und bin daher für jeden rat dankbar.


----------



## Vaethischist (17. Juli 2003)

Du hast schon alles richtig gemacht, aber bei der Ausgabe hast Du einen kleinen (Denk)Fehler.

Ein CString-Objekt kannst Du zwar mit * dereferenzieren, aber das macht nicht so sehr viel Sinn. Du mußt bei der Ausgabe mit cout den CString in ein LPCTSTR casten. Also etwa so:


```
cout << (LPCTSTR) str;
```


----------



## proBier (17. Juli 2003)

hmm das mit dem cout << (LPCTSTR) str funktioniert. wie krieg ich jetzt aber den inhalt in einen String?

```
CStdioFile csFile;
csFile.Open("datei.txt",CFile::modeRead | CFile::typeText);

CString str = "";
CString filecontent = "";
Cstring strtemp;

while (csFile.ReadString( str )) {
  //cout << (LPCTSTR) str << endl;  // das funktioniert
  strtemp = (LPCTSTR) str;
  cout << strtemp << endl;          // funzt nicht
  //filecontent.AppendFormat((LPCTSTR) str);  //das demzufolge auch nicht
}
	
cout << filecontent << endl;        // funzt nicht
		
csFile.Close();
```
Also am Ende soll in filecontent der komplette Dateiinhalt stehen.
Wie stell ich das am besten an?


----------



## Vaethischist (17. Juli 2003)

Du solltest vielleicht mal mein Posting nochmal lesen. Da wo bei Dir "funzt nicht" steht, hast Du den gleichen Fehler gemacht, der schon beim ersten Versuch drin war. 

Der komplette Inhalt der Datei in einem String? Nix leichter als das:


```
CStdioFile csFile;
csFile.Open("datei.txt",CFile::modeRead | CFile::typeText);

CString str = "";
CString filecontent = "";

while (csFile.ReadString( str )) {
  filecontent += str + '\n';
}		
csFile.Close();
```


----------



## proBier (17. Juli 2003)

Danke, das funzt schonmal. Aber hier gleich mein nächstes Problem.

Ich verwende in etwa folgenden Code:

```
BOOL bFound = false; //gibt an ob String gefunden wurde

CStdioFile csFile;
if (csFile.Open(strSearchDirectory + strFileName,CFile::modeRead | CFile::typeText)) {
  if (isStringInFile(searchstr, csFile)) {
    msg.Format(_T(strFileName));	//Die Ausgabe erfolgt an ein ListBox
    pmyListBox->AddString( msg );
    bFound = true;
  }
csFile.Close();
```

Die Sucharbeit erledigt die isStringInFile():

```
// sucht in der Datei, ob der Suchbegriff enthalten ist
bool Ctest3Dlg::isStringInFile(CString strSearchString, CStdioFile &cfFile )
{
  CString strNewLine = "";                            //enthält eine Zeile aus Datei

  while (cfFile.ReadString( strNewLine )) {

    strNewLine = (LPCTSTR) strNewLine.MakeLower();    //strSearchString ist auch "klein"

    if (strNewLine.Find(strSearchString,0) >= 1)      //gefunden
      return true;
  }

  return false;
}
```

Und nun zum Problem das ganze funktioniert mit der Einschränkung, dass Wörter, die zu Beginn in einer Zeile nicht gefunden werden.
Z.B. Inhalt von datei.txt:
Zeile 1: Hallo Welt
Zeile 2: Hello World
Eine Suche nach Welt und World ist erfolgreich die Suche nach Hallo bzw Hello nicht.
Die Suche nach allo bzw. ello ist wiederum erfolgreich.

Ich vermute mal, dass die ReadLine Methode den ersten Buchstaben einer Zeile verschluckt.

Oder wie kann ich das Problem lösen?


----------



## Vaethischist (18. Juli 2003)

_CString::Find()_ liefert die Position des gefundenen Wortes zurück, aber der Index ist *zero based*! Der erste Buchstabe ist also an Position 0, deshalb funktioniert Deine Suche nicht wie gewünscht. Wenn _Find()_ den String nicht finden kann, gibt es *-1* zurück.


----------



## proBier (22. Juli 2003)

Vielen Dank!

Die Zeile muss also lauten:

```
if (strNewLine.Find(strSearchString,0) >= 0)
```


----------

