# datei suche



## dacoma (14. Januar 2004)

Hallo..

ich bin dabei ein kleines Programm zu schreiben mit dem ich auf meiner Festplatte nach allen zip Files suchen kann + alle ausgeben oder nach einem bestimmten zip File suchen kann..
Leider komme ich jetzt nicht mehr weiter und ich hoffe das mir jemand dabei helfen könnte !
Hier jetzt das was ich bis jetzt realisiert habe :

#include <iostream> 
#include <windows.h>
#include<stdio.h>
#include<conio.h>
#include<ctype.h>
#include<screenhelp.h>
using namespace std; 

//---------------------Deklaration der Funktionen-------------------------------
int Suche();
int Ausgabe();
void Menue();
//--------------------------Main------------------------------------------------
main()

{
Menue();
Ausgabe();
Suche();
}

//-------------------Definition der Funktionen----------------------------------

//----------------------- Menue ------------------------------------------------
void Menue()
{
  char z;
  do
   {
    cout<<endl<<"---------------------------Menueprogramm-------------------------------"<<endl;
    cout<<endl<<"Nach Eingabe des Anfangsbuchstaben + Enter erhalten Sie Informationen !"<<endl;
    cout<<endl<<"(1)Suche"<<endl;
    cout<<endl<<"(2)Ausgabe"<<endl;
    z=getch();
    switch(z)
     {
      case '1': Suche(); break;
	  case '2': Ausgabe(); break;

     }
   }while(z!='3');


}
//----------------------- Suche ------------------------------------------------
int Suche()
{

    WIN32_FIND_DATA FData;
    HANDLE hSearch = FindFirstFile("C:\\C\\*12345678*",&FData);
    BOOL MoreFiles = FALSE; 
    int cnt_dir = 0, cnt_file  = 0;

    if (hSearch == INVALID_HANDLE_VALUE) return -1;

    do 
    { 
      // Ist das ein Ordner ?
      if (FData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
      { 
        // Den Ordnernamen ausgeben        
        cout<<"(Ordner) "<<FData.cFileName<<endl;         
        cnt_dir++; // Ordnerzähler um 1 erhöhen
      }

      // Wenn nicht
      else 
      {
        // Den Dateinamen ausgeben
        cout<<"(Datei)  "<<FData.cFileName<<endl; 
        cnt_file++; // Dateizähler um 1 erhöhen 
      }         

      MoreFiles = FindNextFile(hSearch,&FData); 
    } while (MoreFiles); 

    FindClose(hSearch);   

    cout<<endl<<"Insgesamt"<<endl
              <<"Ordner:  "<<cnt_dir<<endl
              <<"Dateien: "<<cnt_file;

    cin.get();
return 0;
}

//------------------- Ausgabe aller zip Files ----------------------------------

int Ausgabe()
{
WIN32_FIND_DATA FData; 

    HANDLE hSearch = FindFirstFile("C:*.zip*",&FData);
    BOOL MoreFiles = FALSE; 
    int cnt_dir = 0, cnt_file  = 0;

    if (hSearch == INVALID_HANDLE_VALUE) return -1;

    do 
    { 
      // Ist das ein Ordner ?
      if (FData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
      { 
        // Den Ordnernamen ausgeben        
        cout<<"(Ordner) "<<FData.cFileName<<endl;         
        cnt_dir++; // Ordnerzähler um 1 erhöhen
      }

      // Wenn nicht
      else 
      {
        // Den Dateinamen ausgeben
        cout<<"(Datei)  "<<FData.cFileName<<endl; 
        cnt_file++; // Dateizähler um 1 erhöhen 
      }         

      MoreFiles = FindNextFile(hSearch,&FData); 
    } while (MoreFiles); 

    FindClose(hSearch);   

    cout<<endl<<"Insgesamt"<<endl
              <<"Ordner:  "<<cnt_dir<<endl
              <<"Dateien: "<<cnt_file;

    cin.get();
return 0;
}

Vielen Dank schonmal !


----------



## sabst (15. Januar 2004)

Du kannst die gefundenen Dateinamen zum Teil oder komplett, wie du's brauchst mit einem anderen String vergleichen.

Unter C nehme ich je nach Bedarf eine der Funktionen: memcmp/strcmp oder strncmp.

Kannst du in C++ genauso nehmen. Falls FData.cFileName kein char-array ist ,musst du auf  char* casten.

Ich hoffe das hilft dir weiter.

Sabst


----------



## sisela (21. Januar 2004)

Habe gerade so etwas geschrieben, vielleicht hilfts...


```
void CFile::search(fstream &FS) {
	
	char savepath[MAX_PATH];	// zur Zwischenspeicherung des Pfades
	int len;
	
	WIN32_FIND_DATA FindFileData;
	HANDLE hFind;
	strcpy(savepath, path);		// Sicherung des Pfades
	strcat(path, "\\*");
	hFind = FindFirstFile(path, &FindFileData);
	if(hFind == INVALID_HANDLE_VALUE) {
		cout << "Datei nicht vorhanden oder anderer Fehler..." << endl << "GetLastError: " << GetLastError () << endl;
	} 
	else {
		do {
			int result = strcmp(FindFileData.cFileName, "."); 
			int result2 = strcmp(FindFileData.cFileName, ".."); 
			if(FindFileData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY && result != 0 && result2 !=0) {
				len=strlen(path);
				strcpy(&path[len-2], "\0");
				strcat(path, FindFileData.cFileName);
				strcat(path, "\\");
				search(FS);
				strcpy(path, savepath);
				strcat(path, "\\*");
			}
			else {
				char file_end[MAX_PATH];
				strcpy(file_end,FindFileData.cFileName);
				len=strlen(file_end);
				strcpy(&file_end[len-4], "\0");
				strcat(file_end, type);
				if((strcmp(file_end, FindFileData.cFileName)) == 0) {
					cout << savepath << FindFileData.cFileName << endl;
				}
			}
		} while(FindNextFile(hFind, &FindFileData));
	}
	FindClose(hFind);
}// end search
```


----------



## Dorschty (10. März 2008)

Hallo,

ich habe ein ähnliches Problem! Ich versuche zunächst einfach eine Datei in einem Verzeichnis zu finden und den Pfad davon mit anzugeben. Das Programm wird dann später noch erweitert.
Ich habe mich an dem oben genannten Quelltext bedient und folgedes zusammengestellt:


```
#include "stdafx.h"
#include "stdio.h"
#include "conio.h"
#include "windows.h"
#include "iostream"
#include "ctype.h"

using namespace std;

#define SEARCH_FOLDER "D:\Suche"

int _tmain(int argc, _TCHAR* argv[])
{
	WIN32_FIND_DATA FData;
	HANDLE hSearch = FindFirstFile("SEARCH_FOLDER",&FData);
	BOOL MoreFiles = FALSE;
	int cnt_file = 0, cnt_dir = 0;
	
	if (hSearch == INVALID_HANDLE_VALUE) return -1;

	do 
	{ 
		// Ist das ein Ordner ?
		if (FData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
		{ 
			// Den Ordnernamen ausgeben 
			cout<<"(Ordner) "<<FData.cFileName<<endl; 
			cnt_dir++; // Ordnerzähler um 1 erhöhen
		}

		// Wenn nicht
		else 
		{
			// Den Dateinamen ausgeben
			cout<<"(Datei) "<<FData.cFileName<<endl; 
			cnt_file++; // Dateizähler um 1 erhöhen 
		} 
		MoreFiles = FindNextFile(hSearch,&FData); 
	} while (MoreFiles); 

	FindClose(hSearch); 

	cout<<endl<<"Insgesamt"<<endl
	<<"Ordner: "<<cnt_dir<<endl
	<<"Dateien: "<<cnt_file;

	_getch();
		
	return 0;
}
```

Wenn ich jetzt debugge, kommt folgender Error:
dateisuche.cpp(18) : error C2664: 'FindFirstFileW' : cannot convert parameter 1 from 'const char [14]' to 'LPCWSTR'
1>        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast.

Ich habe die Zeile mit dem Error fett markiert. Kann mir jemand bei dem Fehler helfen und mir sagen, was ich falsch mache? Ich weiß es leider nicht.

Danke und Gruß
Dorschty


----------



## Teambeta (10. März 2008)

Du hast in deinen Projekteinstellungen wahrscheinlich Unicode, etc. aktiviert, was dazu führt, dass nur die Unicode Funktionen ( von der WinAPI ) benutzt werden.

Lösungsweg #1: Unicode deaktivieren.
Lösungsweg #2: An allen WinAPI Funktionen ein A hinten dranhängen. 

D.h.: FindFirstFileA(..);


----------



## Dorschty (10. März 2008)

Hi Teambeta,

danke schonmal für deine Antwort.
Ich habe das A hinter FindFirstFile angehängt, aber dann bekomme ich folgenden Fehler:
dateisuche.cpp(18) : error C2664: 'FindFirstFileA' : cannot convert parameter 2 from 'WIN32_FIND_DATA *__w64 ' to 'LPWIN32_FIND_DATAA'
1>        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

Wie ich Unicode deaktiviere, weiß ich leider auch nicht.

Gruß
Dorschty


----------



## deepthroat (10. März 2008)

Hi.

Ob die Funktion FindFirstFileA oder FindFirstFileW aufgerufen wird, passiert automatisch.

Du mußt einfach die Stringliterale in _T() einfassen:
	
	
	



```
FindFirstFile("abc"); // nicht so
FindFirstFile(_T("abc")); // sondern so
```
Das funktioniert unabhängig davon ob du Unicode oder MBCS oder ANSI Zeichensätze verwendest.

Gruß


----------



## Dorschty (10. März 2008)

Hey deepthroat,

vielen Dank! Jetzt sind zumindest die Fehler weg! 
Allerdings beendet er das Programm an folgender Stelle:


```
if (hSearch == INVALID_HANDLE_VALUE) return -1;
```

Das heißt ja dann so viel, wie er findet nichts und beendet deswegen! Allerdings ist in dem Verzeichnis eine test.txt Datei. Warum findet er die nicht?

Gruß
Dorschty


----------



## deepthroat (10. März 2008)

Dorschty hat gesagt.:


> Hey deepthroat,
> 
> vielen Dank! Jetzt sind zumindest die Fehler weg!
> Allerdings beendet er das Programm an folgender Stelle:
> ...


Weil du nicht nach ihr suchst. Du suchst nach *SEARCH_FOLDER*. Damit die Präprozessorvariable expandiert wird, darfst du sie nicht in Anführungszeichen schreiben:

```
#define SEARCH_FOLDER "d:/suche"
...
FindFirstFile(_T(SEARCH_FOLDER), ...);
```
Gruß

PS: Bitte achte darauf, das umgekehrte Schrägstriche innerhalb von Strings Spezialzeichen sind und entwertet werden müssen:


```
"d:\suche" // nicht so
"d:\\suche" // sondern so
```
Du kannst auch stattdessen normale Schrägstriche verwenden.


----------



## Dorschty (10. März 2008)

Hey,

super Danke! Jetzt findet er auch etwas! Die Ausgabe ist aber sehr komisch!

Mein Quelltext sieht jetzt folgendermaßen aus:


```
#define SEARCH_FOLDER "D:\\Suche\\*"

int _tmain(int argc, _TCHAR* argv[])
{
	WIN32_FIND_DATA FData;
	HANDLE hSearch = FindFirstFile(_T(SEARCH_FOLDER),&FData);
	BOOL MoreFiles = FALSE;
	int cnt_file = 0, cnt_dir = 0;
	
	if (hSearch == INVALID_HANDLE_VALUE) return -1;

	do 
	{ 
		// Ist das ein Ordner ?
		if (FData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
		{ 
			// Den Ordnernamen ausgeben
			cout<<"(Ordner) "<<FData.cFileName<<endl; 
			cnt_dir++; // Ordnerzähler um 1 erhöhen
		}

		// Wenn nicht
		else 
		{
			// Den Dateinamen ausgeben
			cout<<"(Datei) "<<FData.cFileName<<endl; 
			cnt_file++; // Dateizähler um 1 erhöhen 
		} 
		MoreFiles = FindNextFile(hSearch,&FData); 
	} while (MoreFiles); 

	FindClose(hSearch); 

	cout<<endl<<"Insgesamt"<<endl
	<<"Ordner: "<<cnt_dir<<endl
	<<"Dateien: "<<cnt_file;

	_getch();
		
	return 0;
}
```

Da bekomm ich folgende Ausgabe:

(Ordner) 0012FD3C
(Ordner) 0012FD3C
(Datei) 0012FD3C

Insgesamt
Ordner: 2
Dateien: 1

In dem Ordner Suche existiert allerdings nur eine einzige Test.txt Datei!

Wenn ich das define wie folgt implementiere:


```
#define SEARCH_FOLDER "D:\\Suche\\Test.txt"
```

bekomme ich folgende Ausgabe:

(Datei) 0012FD3C

Insgesamt
Ordner: 0
Dateien: 1

Warum sieht denn die Ausgabe so blöd aus? Warum zeigt der mir nur Hex-Zahlen an und nicht den Dateinamen? Vor allem bei der ersten Ausgabe? Was findet er denn da für Ordner und alles? Ich versteh das leider net.

Gruß
Dorschty

Ps.anke für deine Geduld mit mir!


----------



## Dorschty (10. März 2008)

Hey,

hat sich erledigt, ich hab es mitlerweile selbst hinbekommen! Funktioniert so, wie ich es mir vorstelle! 
Trotzdem vielen Dank für deine Hilfe!

Gruß
Dorschty


----------



## deepthroat (12. März 2008)

Hi.

Eine Sache noch: 
	
	
	



```
// Ist das ein Ordner ?
if (FData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
```
FData.dwFileAttributes enthält Bit-Flags. Der Test würde nicht für Verzeichnisse funktionieren, wo andere Bits auch noch gesetzt sind. Z.B. würde ein verstecktes Verzeichnis als Datei klassifiziert werden...

```
// ist es ein Ordner?
if (FData.dwFileAttributes & FILE_ATTRIBUTES_DIRECTORY)
```
Gruß


----------



## stEEdZ (15. Mai 2008)

Hallo,
erstmal Danke, dieser Thread hat auch mir sehr weitergeholfen! 

Eine Frage hätte ich allerdings diesbezüglich noch:


```
#define SEARCH_FOLDER "C:\\*.zip*"
```
hier suche ich ja nach ZIP-Files.
Wie müsste es aussehen wenn ich erstmal nach allen Partitionen auf dem Computer
suchen wollen würde?

Vielen Dank im Voraus
steedz


----------



## Darkflint (16. Mai 2008)

Es gibt doch bestimmt auch in C eine AND-Anweisung irgendwie^^


----------



## stEEdZ (16. Mai 2008)

hö? 
ne ich meine dass man eben sieht partition C,D,E,F vorhanden zb.


```
#define SEARCH_FOLDER "C:\\*.*"
```

also den Pfad hier quasi noch ne Ebene nach unten durchsuchen...
geht das überhaupt?


----------



## Darkflint (16. Mai 2008)

Aso meinst du das.
Duerfte auch gehen, vermut ich mal. Irgendwie ne Variable statt ner festen Konstante?


----------



## stEEdZ (16. Mai 2008)

Darkflint hat gesagt.:


> Duerfte auch gehen, vermut ich mal. Irgendwie ne Variable statt ner festen Konstante?


Ja klar, Variable hab ich schon eingebaut... 
aber ich wüsste gerne die Art und Weise wie ich auf eine Auflistung der Partitionen komme 

Bitte um Hilfe!


----------



## deepthroat (16. Mai 2008)

Hi.

Du meinst vermutlich nicht die Partitionen, sondern die Laufwerke, oder?!

Das kannst du dann mit der Funktion GetLogicalDriveStrings() (siehe MSDN) machen:

```
#define _WIN32_WINNT 0x0501

#include <windows.h>

TCHAR buf[MAX_PATH];
  
DWORD c = GetLogicalDriveStrings(MAX_PATH, buf);
if (c < MAX_PATH && c > 0) {
  for (TCHAR* p = buf; p < buf + c; p += 1 + strlen(p)) 
    {
      puts(p);
    }
}
```
Gruß


----------



## stEEdZ (17. Mai 2008)

Danke genau das meinte ich!!

so natürlich haben sich hiermit neue Probleme für mich eröffnet 


```
int _tmain(int argc, _TCHAR* argv[])
{
    int i = 0, n;
	string * vPartition;
	vPartition = new string[n];
	
	TCHAR buf[MAX_PATH];
    DWORD c = GetLogicalDriveStrings(MAX_PATH, buf);
    if (c < MAX_PATH && c > 0) {  
          for (TCHAR* p = buf; p < buf + c; p += 1 + strlen(p))     {
                    vPartition[i] = p;
                    i++;
                    
          }
    }
    string holder = vPartition[0];
    char * drive;
    char * tmp;
    
    tmp = &holder[0];
    
    for(i = 0; i < (strlen(tmp) - 1); i++)
    {     
          drive[i] = tmp[i];
    }
    
    strcat(drive,"//*");
    cout<<drive<<endl;
    
    _tSearchPath(drive);
    
    delete[] vPartition;
    system("PAUSE");
    return 0;
}
```

Problem 1:
mit GetLogicalDriveStrings bekomme ich meine Laufwerke so "C:\" geschrieben. Das heisst ich kann sie nicht einfach in einen string kopieren und den dann als Pfad verwenden, sondern muss die Schreibweise erst abändern.
Das hab ich hiermit versucht, aber ich bekomme immer ein Zeichen zuviel mit in das Array, keine Ahnung warum 


```
for(i = 0; i < (strlen(tmp) - 1); i++)
    {     
          drive[i] = tmp[i];
    }
    
    strcat(drive,"//*");
    cout<<drive<<endl;
```

Problem 2:
da ich später dann mit "FindFirstFile" arbeite benötige ich ja den Pfad als Char File.
Deswegen converte ich hier auch string to char

```
string holder = vPartition[0];
    char * drive;
    char * tmp;
    
    tmp = &holder[0];
```
.... aber besonders elegant ist das sicher nicht. Hat da jemand vielleicht ne bessere Lösung?

Vielen Dank im Voraus
stEEdZ


----------



## devDevil (17. Mai 2008)

Mehrere Fehler drin ... 
1. Du kannst nur bei std::vector davon ausgehen, dass die Elemente hintereinander im Speicher liegen. (=> &string[0] solltest du besser lassen)
2. std::string muss intern nicht Nullterminieren.
3. Du hast für drive keinen Speicher angefordert. WO du jetzt gerade geschrieben hast ... will ich gar nicht wissen 
4. Nicht TCHAR und char mischen, wenn du nicht weißt was du da tust


----------



## stEEdZ (17. Mai 2008)

Ok, danke schonmal!
Und wie müsste das dann richtig aussehen? Ich weiss es wirklich nicht besser


----------



## devDevil (17. Mai 2008)

Nja ich weiß nicht ganz wie dein String am Ende aussehen soll ...


```
#include <windows.h>
#include <iostream>
#include <string>


int main()
{
    char buffer[1024];
    const DWORD result(::GetLogicalDriveStringsA(1024, buffer));
    if (result > 1024) { std::cerr << "FEHLER: Buffer zu klein!"; return 1; }
    else if (result == 0) { std::cerr << "FEHLER: Kein Laufwerk gefunden!"; return 1; }

    for (char* ptr_item = buffer; *ptr_item; ptr_item += std::strlen(ptr_item) + 1)    
    {
        std::string current_drive(ptr_item);
        current_drive.append("//*");
        std::clog << current_drive << std::endl;

        _tSearchPath(current_drive.c_str());
    }
   
    std::cin.get();
}
```
 ... so mal einfach deinem Code folgend ...


----------



## stEEdZ (18. Mai 2008)

Es funktioniert!
Vielen Dank an euch deepthrout und devDevil!


----------



## Krikus (2. Dezember 2009)

Dorschty hat gesagt.:


> Hey,
> 
> super Danke! Jetzt findet er auch etwas! Die Ausgabe ist aber sehr komisch!
> 
> ...



Hab das selbe Problem. und will keinen neuen Thread dafür aufmachen. Weiß einer wie ich dies ändern kann?


----------



## deepthroat (2. Dezember 2009)

Krikus hat gesagt.:


> Hab das selbe Problem. und will keinen neuen Thread dafür aufmachen. Weiß einer wie ich dies ändern kann?


Du hast vermutlich die UNICODE Unterstützung aktiviert und demnach versucht einen wchar_t* auszugeben, dabei wird dann nur die Adresse des Zeigers ausgegeben.

Entweder du konvertierst die wide-char Strings zu normalen Strings, verwendest für die Ausgabe wcout, wcerr usw. oder du schaltest die Unicode Unterstützung aus. \edit: Oder verwende eine der generischen Ausgabefunktionen _tprintf, _putts zur Ausgabe der gefundenen Dateinamen.

Gruß


----------



## Krikus (2. Dezember 2009)

Danke für die Antwort.

Habe nun wcout genommen.

Wie kann ich den nun mit den Dateinamen arbeiten ohne Strings zu benutzen und Unicode auszuschalten.

z.B ich hab in dem Ordner die Dateien:

xyz.mp3
xyz_1.mp3
xyz_2.mp3
xyz_3.mp3
........

Nun soll xyz.mp3 in xyz_4.mp3 umbenannt werden. Die Zahlnendung hängt davon ab wieviele DAteien bereits vorhanden sind. bzw. was die nächste Zahl in der Reihenfolge ist. Dazu würde ich jetzt schauen, wie oft "xyz_" im Dateinamen vorkommt , und so die nächste Zahl ermitteln.

Das umbenenne würde ich mit 


```
errno_t err = rename(filename, newname);
```
machen. 

Letztendlich soll es für eine Logfile Rotation dienen. 
Oder gibt es da schon was fertiges


----------



## deepthroat (2. Dezember 2009)

Krikus hat gesagt.:


> Wie kann ich den nun mit den Dateinamen arbeiten ohne Strings zu benutzen und Unicode auszuschalten.


Du verwendest grundsätzlich die generischen Funktionen und Typen aus tchar.h. Siehe http://msdn.microsoft.com/en-us/library/tsbaswba(VS.80).aspx


Krikus hat gesagt.:


> Nun soll alarm.mp3 in alarm_4.mp3 umbenannt werden. Die Zahlnendung hängt davon ab wieviele DAteien bereits vorhanden sind. bzw. was die nächste Zahl in der Reihenfolge ist. Dazu würde ich jetzt schauen, wie oft "alarm_" im Dateinamen vorkommt , und so die nächste Zahl ermitteln.
> 
> Das umbenenne würde ich mit
> 
> ...


Das würde nicht funktionieren. Du mußt _trename verwenden.

Gruß


----------



## Gerier (16. Februar 2010)

Hallo, 

wie kann man denn unterordner mitzählen lassen ? 

MfG Gerier


----------



## michback (22. Februar 2010)

sisela hat gesagt.:


> Habe gerade so etwas geschrieben, vielleicht hilfts...
> 
> 
> ```
> ...



Ich wollte Datein und habe mir diesen Quellcode von oben rausgesucht


```
#include <vcl.h>
#include <iostream>
#include <windows.h>
using namespace std;
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}

void CFile::search(fstream &FS) {

	char savepath[MAX_PATH];	// zur Zwischenspeicherung des Pfades
	int len;

	WIN32_FIND_DATA FindFileData;
	HANDLE hFind;
	strcpy(savepath, path);		// Sicherung des Pfades
	strcat(path, "\\*");
	hFind = FindFirstFile(path, &FindFileData);
	if(hFind == INVALID_HANDLE_VALUE) {
		cout << "Datei nicht vorhanden oder anderer Fehler..." << endl << "GetLastError: " << GetLastError () << endl;
	}
	else {
		do {
			int result = strcmp(FindFileData.cFileName, ".");
			int result2 = strcmp(FindFileData.cFileName, "..");
			if(FindFileData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY && result != 0 && result2 !=0) {
				len=strlen(path);
				strcpy(&path[len-2], "\0");
				strcat(path, FindFileData.cFileName);
				strcat(path, "\\");
				search(FS);
				strcpy(path, savepath);
				strcat(path, "\\*");
			}
			else {
				char file_end[MAX_PATH];
				strcpy(file_end,FindFileData.cFileName);
				len=strlen(file_end);
				strcpy(&file_end[len-4], "\0");
				strcat(file_end, type);
				if((strcmp(file_end, FindFileData.cFileName)) == 0) {
					cout << savepath << FindFileData.cFileName << endl;
				}
			}
		} while(FindNextFile(hFind, &FindFileData));
	}
	FindClose(hFind);
}// end search
//---------------------------------------------------------------------------
```

Dies ist mein Programm mit eingefügten Quelltext. 

Als Fehler kommt: 

//////
[BCC32 Fehler] Unit1.cpp(20): E2090 Qualifizierer 'CFile' ist kein Name einer Klasse oder eines Namespace
[BCC32 Fehler] Unit1.cpp(20): E2040 Deklaration nicht ordnungsgemäß abgeschlossen
/////

Ich muss dazu sagen ich komme von Delphi und habe mir jetzt  c++ vorgenommen. Ich habe die Grundlagen mit einem Buch gelernt. Und bin jetzt dabei alle Programme in c++ nachzuschrieben. Das einzigste Problem ist eben das ich eine Suchroutine benötige.Welche

alle *.avi mit Dateiname und Pfad in einer ListBox auflistet. 


P.S.: Ich wäre auch Dankbar über ein Tutorial zur Datei arbeit oder ein gutes Buch.


----------



## deepthroat (22. Februar 2010)

michback hat gesagt.:


> Als Fehler kommt:
> 
> //////
> [BCC32 Fehler] Unit1.cpp(20): E2090 Qualifizierer 'CFile' ist kein Name einer Klasse oder eines Namespace
> ...


Wie bereits da steht, du hast weder eine Klasse noch einen Namensraum der "CFile" heißt definiert.

Deshalb kannst du auch nicht definieren, das es eine Methode namens search für diese Klasse oder Namensraum geben soll.

Lass einfach das "CFile::" bei der Definition weg.

Ist dir außerdem bewußt das in dem Code den du ausgewählt hast noch ein paar Fehler sind, über die wir in dem Thema diskutiert hatten?!

Gruß


----------



## michback (22. Februar 2010)

deepthroat hat gesagt.:


> Wie bereits da steht, du hast weder eine Klasse noch einen Namensraum der "CFile" heißt definiert.
> 
> Deshalb kannst du auch nicht definieren, das es eine Methode namens search für diese Klasse oder Namensraum geben soll.
> 
> ...



Danke erst mal. Ich habe die Diskussion gelesen. Habe aber vieles nicht verstanden.  Es sind einfach zuviele Anweisungen bei denen ich nicht weis, was diese genau machen. In Delphi habe ich WindowsAPI Funktionen verwendet. Ich versuchen mal das für c++ umzuformatieren.

Mir fehlt eine Dokumentaion welche mich von einem jetzigen Stand zu der Dateiverarbeitung bringt. Leider finde ich keine guten Tutorials oder Anleitungen.

Habe ein Tutorial gefunden:


```
#include <vcl.h>
#pragma hdrstop

#include "findfirst_form.h"
#include "dir.h"
//---------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)

{
  int iAttributes = 0;

  iAttributes |= faReadOnly * CheckBox1->Checked;
  iAttributes |= faHidden * CheckBox2->Checked;
  iAttributes |= faSysFile * CheckBox3->Checked;
  iAttributes |= faVolumeID * CheckBox4->Checked;
  iAttributes |= faDirectory * CheckBox5->Checked;
  iAttributes |= faArchive * CheckBox6->Checked;
  iAttributes |= faAnyFile * CheckBox7->Checked;

  // Reset the grid, display a default failure message (which will
  // be overwritten if a file is found)
  StringGrid1->RowCount = 2;
  StringGrid1->FixedRows = 1;
  StringGrid1->Rows[0]->CommaText = "Filename,Size,Attributes";
  StringGrid1->Cells[0][1] = "No Files Found";
  StringGrid1->Cells[1][1] = "";
  StringGrid1->Cells[2][1] = "";
  StringGrid1->Visible = true;

  displayFiles(Edit1->Text, iAttributes, 1);

  if (StringGrid1->RowCount > 2) StringGrid1->RowCount--;
}


//---------------------------------------------------------------------

void TForm1::displayFiles(AnsiString path, 
                          int iAttributes, 
                          int nestingLevel)
{
  TSearchRec sr;

  // Creating the nesting prefix for displaying with each file name
  AnsiString nesting = "";
  for (int i = 0; i < nestingLevel; i++)
    nesting += "  ";

  if (FindFirst(path, iAttributes, sr) == 0)
  {
    do
    {
      {
        StringGrid1->Cells[0][StringGrid1->RowCount-1] = nesting + sr.Name;
        StringGrid1->Cells[1][StringGrid1->RowCount-1] = IntToStr(sr.Size);
        StringGrid1->Cells[2][StringGrid1->RowCount-1] = 
             "0x" + IntToHex(sr.Attr & faAnyFile, 2);
        StringGrid1->RowCount = StringGrid1->RowCount + 1;
        if ((sr.Attr & faDirectory) && DrillDirectories->Checked) {
          // Do not drill into "." or ".."
          if (sr.Name != "." && sr.Name != "..") {
            AnsiString drillPath = appendDirectory(path, sr.Name);
            displayFiles(drillPath, iAttributes, (nestingLevel+1));
          }
        }
      }
    } while (FindNext(sr) == 0);
    FindClose(sr);
  }


  // If we are supposed to drill into directories but the faDirectory flag
  // was not set, that means findFirst skipped all of the directories.  Do
  // the search again, this time only looking for directories so that we
  // can drill into them.
  //
  if (DrillDirectories->Checked && ((faDirectory & iAttributes) == 0)) {
    // Use driveAndPath() to Create a path that does not contain a
    // filename or extension so that directories can be drilled into
    if (FindFirst(driveAndPath(path) + "*",
                  iAttributes | faDirectory,
                  sr) == 0)
    {
      do {
        if (sr.Attr & faDirectory) {
          if (sr.Name != "." && sr.Name != "..") {
            // When we find a directory that can be drilled into,
            //  recurse into that directory so that the matching
            //  files can be displayed.
            displayFiles(appendDirectory(path, sr.Name), 
                         iAttributes, 
                         nestingLevel+1);
          }
        }
      } while (FindNext(sr) == 0);
    }
    FindClose(sr);
  }
}


// Append the newDir directory to the path, retaining any 
// filename that might already be on the path.
//
AnsiString TForm1::appendDirectory(AnsiString path, AnsiString newDir)
{
  char drillIntoPath[MAXPATH];
  char drive[MAXDRIVE];
  char dir[MAXDIR];
  char file[MAXFILE];
  char ext[MAXEXT];

  fnsplit(path.c_str(),drive,dir,file,ext);

  strcat(dir, newDir.c_str());

  fnmerge(drillIntoPath,drive,dir,file,ext);

  return(AnsiString(drillIntoPath));
}



// Given a fully qualified filename, return just the drive and
// path.
//
AnsiString TForm1::driveAndPath(AnsiString path)
{
  char drillIntoPath[MAXPATH];
  char drive[MAXDRIVE];
  char dir[MAXDIR];
  char file[MAXFILE];
  char ext[MAXEXT];

  fnsplit(path.c_str(),drive,dir,file,ext);

  fnmerge(drillIntoPath,drive,dir,0,0);

  return(AnsiString(drillIntoPath));
}
```


----------



## Vereth (23. Februar 2010)

Vielleicht findest du hier ein paar nützliche Anregungen. Eine Referenz für C/C++ findest du auf der Site auch.
http://www.cplusplus.com/src/


----------

