3.1k Aufrufe
Gefragt in Anwendungen(Java,C++...) von
Hallo allerseits!

Ich habe folgendes Problem:
Ich habe eine Klasse die in ein Member-Array die Namen eines Verzeichnisslistings schreiben soll. Der Code funktioniert soweit auch ausser, dass ich nur ein statisches Array verwenden kann, da ich nicht weiß wie man dies mit einem dynamischen Array macht... bzw. das nicht klappt...

in meiner Header-Datei steht in etwa das:

#ifndef MEINEKLASSE
#define MEINEKLASSE

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

class MeineKlasse{
private:
std::wstring ArrayKat[];
public:
MeineKlasse();
~MeineKlasse();
};

#endif //MEINEKLASSE

und in meiner Datei steht das hier:

#include "MeineKlasse.h"
using namespace std;

#include "string_functions.h"


MeineKlasse::MeineKlasse(){

wstring Ordner = _wgetcwd(NULL, 0) + (wstring) L"\\UnterOrdner\\*";

WIN32_FIND_DATA wfd;
HANDLE fHandle = FindFirstFile(Ordner.c_str(),&wfd);
int Index = 0;

do{
if (!( (wfd.cFileName[0]=='.') && ( (wfd.cFileName[1]=='.' && wfd.cFileName[2]==0) || wfd.cFileName[1]==0 ) )){
if (!(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)){//wenn kein Ordner

ArrayKat[Index] = (wstring) wfd.cFileName;
Index++;
}
}
}while (FindNextFile(fHandle,&wfd));
FindClose(fHandle);

// MessageBox(NULL,Ordner.c_str(), Str(AnzWitze).c_str(), MB_OK);
};

MeineKlasse::~MeineKlasse(){
}


Compilieren tuts ganz gut, aber beim Ausführen bricht das Programm ab :(
Wie mache ich das jetzt am besten, vei Google und Co weiß ich nicht genau nach was ich zu suchen hab...

6 Antworten

0 Punkte
Beantwortet von bored Mitglied (197 Punkte)
Hallo.

Warum soll das in einen Array? Pack's doch in ne Liste!

Aber da du den Array schon komplett falsch gebrauchst, gehe ich mal davon aus, dass du dich mit C/C++ nicht so gut auskennst und deswegen auch mit Generics Probleme haben könntest...

Was passiert denn bei diesem Befehl?
private:
std::wstring ArrayKat[];

Es wird ein POINTER auf einen Speicherbereich gelegt. Allerdings hast du den Speicherbereich nicht reserviert. Du überschreibst also wahllos irgendwo deinen Haupspeicher, weswegen das Betriebssystem dein Programm abschießt.
Jedenfalls hast du zwei Möglichkeiten: Entweder du zählst die Anzahl der Dateien vorher und reservierst im Konstruktor den nötigen Speicher, oder aber du hast eine eigene Funktion, die Daten hinzufügt.
Da ich eher ein C-Mann bin, kommt hier mal meine Lösung ohne Gewähr (mit flexibler Speicherverwaltung):

class DirectoryListing{
private:
std::wstring ArrayKat[];
int size;
public:
DirectoryListing();
~DirectoryListing();
addFile(std::wstring filename);
findFiles(std::wstring dir);
};

DirectoryListing::DirectoryListing() {
ArrayKat = NULL;
size = 0;
}

DirectoryListing::~DirectoryListing() {
}

DirectoryListing::addFile(std::wstring filename) {
int idx = size;
size++;
ArrayKat = realloc(ArrayKat, size * sizeof(std::wstring));
ArrayKat[idx] = filename;
}

// die nächste ist von dir kopiert, das "dir" ist natürlich passend einzusetzen.
DirectoryListing::findFiles(std::wstring dir) {
// hier irgendwie das "dir" vernünftig verwenden
wstring Ordner = _wgetcwd(NULL, 0) + (wstring) L"\\UnterOrdner\\*";

WIN32_FIND_DATA wfd;
HANDLE fHandle = FindFirstFile(Ordner.c_str(),&wfd);
int Index = 0;

do{
if (!( (wfd.cFileName[0]=='.') && ( (wfd.cFileName[1]=='.' && wfd.cFileName[2]==0) || wfd.cFileName[1]==0 ) )){
if (!(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)){//wenn kein Ordner

// NEIN
//ArrayKat[Index] = (wstring) wfd.cFileName;
//Index++;
addFile( (wstring) wfd.cFileName );
}
}
}while (FindNextFile(fHandle,&wfd));
FindClose(fHandle);

// MessageBox(NULL,Ordner.c_str(), Str(AnzWitze).c_str(), MB_OK);
};

}


außerdem solltest du dir angewöhnen, solche dicken Befehle aus dem Konstruktor rauszulassen - dafür ist der nicht gedacht.


mfg
0 Punkte
Beantwortet von bored Mitglied (197 Punkte)
Ups, der Destruktor ist jetzt natürlich blödsinn, da er den reservierten Speicherbereich wieder freigeben muss!


DirectoryListing::~DirectoryListing() {
free(ArrayKat);
}
0 Punkte
Beantwortet von Experte (3.2k Punkte)
in c macht man das manuell mit den alloc-befehlen (siehe oben) und (faule) c++ler nehmen dafür n fertiges template.
in deinem fall wäre das der std:vector!
such einfach n bisschen mit google, wie der zu verwenden ist. das ist ein lifo bzw filo speicher, also wie ein stack.
mit push_back() und pop_back() kannst du elemente einfügen oder entfernen, auf die elemente kann man wie bei einem array mit [index] zugreifen. size() liefert die anzahl der elemente.

dazu siehe auch hier

zur verwendung könnte ich mir jetzt n beispiel aus den fingern saugen, jedoch denke ich, diese seite kann das n bisschen besser. ;)

Ele
0 Punkte
Beantwortet von
Ja danke erstmal für die Antwort, aber jetzt meckert der Compiler über diese Zeile

ArrayKat = realloc(ArrayKat, size * sizeof(std::wstring));


und zwar sagt er:

C:\Users\Fabian\Projects\Test\dateiliste.cpp|65|error: incompatible types in assignment of `void*' to `std::wstring[0u]'|


übrigens hat der schon gemeckert das er einen Typ für die Funktionen habe will, also habe ich ein void davor geschrieben....
0 Punkte
Beantwortet von bored Mitglied (197 Punkte)

C:\Users\Fabian\Projects\Test\dateiliste.cpp|65|error: incompatible types in assignment of `void*' to `std::wstring[0u]'|

Jaaaah.. ich nehme mal an, es sollte reichen, das Ergebnis von realloc nach wstring zu casten - im Endeffekt ist es an dieser Stelle ja egal, von welchem Typ ArrayKat speziell ist.



in c macht man das manuell mit den alloc-befehlen (siehe oben) und (faule) c++ler nehmen dafür n fertiges template.

Naja, meine Kenntnisse in C++ beschränken sich auf einfache Klassen mit Konstruktoren und Destruktoren ^^
Trotzdem finde ich es sinnvoll, dass Neulinge den Kram gleich RICHTIG lernen, auch wenn man es in C++ nicht mehr so häufig braucht. Wenn man sich mit der Speicherverwaltung nicht auseinandersetzen will, könnte man ja auch Java benutzen oder so ;)
0 Punkte
Beantwortet von
mh nein das klappt nicht. irgendwie mach ich immer was falsch...
Jetzt kommt zusätzliczh noch:

C:\Users\Fabian\Projects\Test\dateiliste.cpp|65|error: invalid conversion from `void*' to `const wchar_t*'|


ich les mir das mit den list oder vector mal durch, vllt klappt das ja...
...