O
DocShoe schrieb:
Ein paar Worte zu wcscpy :
Die Signatur ist wchar_t *wcscpy( wchar_t *dest, const wchar_t *src ) . Diese Funktion kopiert C-Style string von source nach dest , der String muss nullterminiert sein. Der erste Parameter ist das Ziel, der zweite die Quelle, das ist in deinem Code schon mal falsch. Außerdem bist du als Aufrufer dafür verantwortlich, dass der Speicherbereich des Ziels groß genug ist, um den kompletten String aufzunehmen.
In deiner Variante 2 übergibst du UnicodeStrings , das passt von der Signatur nicht und wird vom Compiler zu recht als Fehler erkannt.
Variante 3 dürfte eigentlich auch nicht übersetzt werden, da UnicodeString::c_str einen const wchar_t* zurückgibt und als erster Parameter von Target nicht zur wcscpy -Signatur passt. Vermutlich drückt da der klassische Compiler wieder beide Augen zu und lässt den Schreibzugriff auf einen const Pointer zu. Abgesehen davon ist auch nicht sichergestellt, dass der Speicherbereich, auf den Target.c_str() zeigt, groß genug ist, um den Inhalt von Source aufzunehmen.
Außerdem:
In Zeile 26 meines Codes rufst du ShowMessage auf. Das Zusammensetzen des Textes funktioniert nicht so, wie du vermutest, sondern so:
"Error: " wird zu einen const char* ausgewertet, auf den du das Ergbnis des GetLastError() -Aufrufs addierst. Damit verschiebst du den Zeiger um ein paar Bytes nach vorne und deshalb wird auch nicht die korrekte Fehlermeldung angezeigt, sondern nur ein Bruchteil des Textes. Bei Rückgabewerten >7 greifst du auf ungültigen Speicher zu und erzeugst mit deinem Programm undefiniertes Verhalten.
Ich habe den Eindruck, dass die bei ein paar Sachen das grundlegende Verständnis fehlt, da solltest du dir noch mal dein C++ Buch schnappen und lesen.
Aus Interesse:
Warum gibt´s zwei geschachtelte try-catch Blöcke? In deinem gezeigten Quelltext gibt es keine Stelle, an der eine Exception geworfen werden könnte.
Edit:
Du hast die code-tags geschachtelt und das mag der Parser nicht.
UnicodeString Source;
UnicodeString Target = FDBModul->ExePfad + "HotSave\\" + strWTag + "\\";
try {
for (int i = 0; i < FileListBox3->Items->Count; i++) {
try {
Source = FDBModul->DBPfad + FileListBox3->Items->Strings[i];
Getan = CopyFileW(Source.w_str(), Target.w_str(), false); // Variante 1
// keine Fehlermeldung vom compiler aber nur beim ersten Durchlauf Kopien
// gemacht
Getan = wcscpy(Source, Target); // Variante 2
// Fehlermeldung: keine Kovertierung von Unicode nach wchar_t
Getan = wcscpy(Source.w_str(), Target.w_str()); // Variante 3
// keine Fehlermeldung vom compiler aber auch keine Kopien gemacht, Getan
// wurde aber 135x auf true gesetzt
if (Getan)
Count++;
}
catch(...) { }
if (!Getan)
ShowMessage("Error: " + GetLastError()); // Bei der Anzeige kam nur "or."
// diese Fehlermeldung habe ich natürlich nur mit 2 oder 3 Files probiert
Getan = false;
}
Hallo DocShoe
Vielen Dank für die prompte Antwort, dazu folgende Stellungname:
Variante 1
Die Original-Definition von MS für die Fuktion CopyFile lautet:
BOOL CopyFile(
LPCTSTR lpExistingFileName,
LPCTSTR lpNewFileName,
BOOL bFailIfExists
);
somit ist der erste Parameter die Quelle und der zweite das Ziel.
Es muss aber einen Grund haben, warum der Compiler den Code akzeptiert, die Ausführung nur 1x geklappt hat?
Eine Abfrage nach dem Ziel-Speicherplatz erübrigt sich bei meiner Anwendung, da es sich um festgelegte, ausreichend dimensionierte Ordner handelt, zwischen denen jeweils hin und her kopiert wird.
Variante 2
Dass der Compiler die Signatur nicht akzeptiert, ist mir klar aber ich möchte gerne wissen, wie der Code aussehen muss, dass ich mit den UnicodeString-Variablen die Dateien kopieren kann.
Variante 3
Hier ist die Sache genauso gelagert wie bei Variante 1, dass der Compiler den Ausdruck "Source.w_str()" klaglos akzeptiert aber das Programm das Kopieren nicht auführt.
Dass die doppelten try-Blöcken unnötig sind, das hast Du natürlich richtig erkannt, wie es zu diesen Lapsus kam kann ich nicht mehr sagen!
Gruß Gert