Die lange, erklärende und hilfreichere Version von TGGCs Post (und die korrektere denn er initialisiert schließlich seine Variablen...):
Du hast gleich mehrere Denkfehler.
LPCWSTR steht für "long pointer [to a] constant wide string". Es entspricht also
const wchar_t*.
C-Strings sind Arrays von Zeichen, also (w)char(_t)[]. Das ist ja auch irgendwie logisch, denn diese Zeichen müssen ja auch irgendwo gespeichert werden.
In deinem Code erstellst du die Zeichenkette L"Hallo" (ein
konstantes Feld mit den Werten 'H', 'a', 'l', 'l', 'o', 0). Dein wchar_t* String1, dem du das zuweist zeigt jetzt also auf das erste Element des Feldes.
Das man nur Zeiger auf Felder verwendet ist auch der Grund, warum C-Strings überhaupt mit Funktionen wie wcscpy kopiert werden müssen, und warum s1 = s2 nicht funktioniert (zumindest nicht so wie man annehmen könnte).
Wenn du dieses Feld in ein anderes kopieren willst, dann muss in dem anderen Feld natürlich auch genug Platz für die 6 Zeichen des ersten Feldes sein.
wcscpy ist (in VC++ 2010) so definiert: (mit ein paar ergänzenden Kommentaren meinerseits)
|
C-/C++-Quelltext
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
/***
*wchar_t *wcscpy(dst, src) - copy one wchar_t string over another
*
*Purpose:
* Copies the wchar_t string src into the spot specified by
* dest; assumes enough room. <---- WICHTIG
*
*Entry:
* wchar_t * dst - wchar_t string over which "src" is to be copied
* const wchar_t * src - wchar_t string to be copied over "dst"
*
*Exit:
* The address of "dst"
*
*Exceptions:
*******************************************************************************/
wchar_t * __cdecl wcscpy(wchar_t * dst, const wchar_t * src)
{
wchar_t * cp = dst;
while( *cp++ = *src++ ) // Zeigerarithmetik: ++ "schiebt" den Zeiger um sizeof(wchar_t) Bytes "weiter".
; /* Copy src over dst */
return( dst );
}
|
Daraus erkennt man folgendes:
1. Der erste Parameter gibt das Ziel an und nicht, wie von dir angenommen, der zweite.
2. Die Funktion ist eigentlich ganz simpel: Die beiden Felder werden durchgegangen, bis die abschließende 0 des Ausgansgfeldes erreicht wurde. Dabei wird jedes Zeichen vom Ausgangsfeld ins Zielfeld kopiert.
Damit das korrekt funktionieren kann muss dst natürlich auf ein Feld zeigen, das Platz für mindestens so viele Zeichen bietet, wie das Feld von src enthält (bis zu der abschließenden 0 einschließlich, bei "Hallo" also 6).
Du erstellst allerdings einfach einen const wchar_t* mit dem Wert 0. Das "const" darin verhindert sowieso Schreibezugriffe, weshalb dein Code nicht kompiliert werden kann. Wenn du durch den cast zu (wchar_t*) das const entfernst, dann brich er im Debugmodus mit einer Ausnahme (Zugriffsverletzung beim Lesen an Position 0x00000000.) ab. (denn String2 ist 0, also hexadezimal 0x00000000)
Deshalb sind C-Style casts imo böse. static_cast, reinterpret_cast und co. sind die bessere Wahl, denn reinterpret_cast würde sich hier direkt darüber beschweren (in Form eines Compilerfehlers), dass Qualifizierer verloren gehen (das const).
Korrekt müsste dein Code ungefähr so aussehen:
|
C-/C++-Quelltext
|
1
2
3
4
|
LPCWSTR String1 = L"Hallo";
// Array mit mindestens 6 Elementen. Mehr schadet nicht, weniger schon.
wchar_t String2[6] = {0}; // Initialisierung setzt alle Werte des Feldes auf 0. Nicht unbedingt notwendig, aber sicherer.
wcscpy(String2, String1);
|
Auch wenn C-Strings ein sehr gutes Training für den Umgang mit Zeigern und Feldern sind, für den produktiven Einsatz ist std::string (bzw. std::wstring) viel besser geeignet. Dann würde sich dein Code auf folgenden, deutlich weniger fehleranfälligen und deutlich eleganteren Code reduzieren:
|
C-/C++-Quelltext
|
1
2
|
std::wstring String1 = L"Hallo";
std::wstring String2 = String1;
|