Komische Zeichen

07/04/2012 22:37 theredvex#1
Hallo nocheinmal,

ich habe gerade mit Folgender Funktion einen Pointer ausgelesen
Code:
wchar_t *buffer;
    int len = wcslen((wchar_t*)PtrString);
    buffer = new wchar_t[len+1];

    wcscpy(buffer,(wchar_t*)PtrString);
    char * charbuffer = new char[wcslen(buffer)+1];
    wcstombs(charbuffer,buffer,wcslen(buffer));
Wie man vlt erkennen kann, lese ich erst nen UNICODE string ausm Ram und convertiere ihn dann in CHAR/String. da kommt leider folgendes Ergebnis raus.
Quote:
LoadingÍýýýýÝÝÝÝÝÝÏ·Õ§w
wie entferne ich, oder sorge schon bei der Convertierung vor, sodass die nichtlesbaren zeichen nicht mitkonvertiert werden?
07/05/2012 14:24 Nightblizard#2
Hey,
du solltest dir folgende Funktionen einmal genauer anschauen:
[Only registered and activated users can see links. Click Here To Register...]
[Only registered and activated users can see links. Click Here To Register...]

Oder du machst es gleich sauber und nutzt C++:
Code:
	const wchar_t* nastyPtr = L"Hallo Welt";
	std::wstring wstr = nastyPtr; //Natürlich kannst du nastyPtr durch L"Hallo Welt" ersetzen. Das habe ich nur geschrieben, da du etwas von einem Pointer erzählt hast.
	std::string str(wstr.begin(), wstr.end());

	std::cout << str << std::endl;
Damit ist es auch gleich Plattformunabhängig, sauberer und wahrscheinlich auch schneller.
07/05/2012 20:43 MrSm!th#3
Quote:
WideCharToMultiByte
Arbeitet doch genau wie wcstombs und std::string wird in seinem Konstruktor wohl das gleiche Problem haben.

Liegt es vielleicht daran, dass im Speicher das 0 Byte fehlt?
Was ist denn, wenn du den String mal wirklich als UNICODE String ausgibst? Sind da irgendwelche Zeichen, die nicht im ASCII Code dargestellt werden können oder wieso willst du eben solche rausfiltern?
Sieht für mich eher nach nem Versuch aus, Zeichen umzuwandeln, die nicht dazugehören.
07/05/2012 21:07 Nightblizard#4
Nein, std::string hat nicht das gleiche Problem, ansonsten hätte ich diese Lösung nicht vorgeschlagen.

Der Grund warum sein Code nicht funktioniert ist, weil new char[x] einfach nur x Elemente für sein Char-Array allokiert. Er behandelt das Char-Array wie einen String, jedoch muss ein C-String durch eine Null terminiert werden und das ist hier einfach nicht der Fall, deshalb wird mehr ausgegeben als eigentlich im String steht (bis zur nächsten 0 im RAM).

Sprich, er kann auch einfach vor wcstombs ZeroMemory(charbuffer, wcslen(buffer)+1); schreiben, doch wie ich bereits sagte, die C++ Variante ist um Welten lesbarer als dieser kryptische Mist.

C++ kann so schön sein, wenn man es denn auch nutzt.
07/05/2012 21:33 Dr. Coxxy#5
C tuts auch.

was machst du da eigtl für seltsames zeug?
warum kopierst du den string erst in einen buffer?
machst du dazwischen noch i-was?


Das hier sollte gehen, wenn nicht noch zusätzlich das zutrifft, was MrSmith vermutete.
Code:
int len = wcslen((wchar_t*)PtrString);
char* CharBuf = new char[len+1];
wcstombs(CharBuf, (wchar_t*)PtrString, len+1);
07/05/2012 22:21 MrSm!th#6
Quote:
Originally Posted by Nightblizard View Post
Nein, std::string hat nicht das gleiche Problem, ansonsten hätte ich diese Lösung nicht vorgeschlagen.

Der Grund warum sein Code nicht funktioniert ist, weil new char[x] einfach nur x Elemente für sein Char-Array allokiert. Er behandelt das Char-Array wie einen String, jedoch muss ein C-String durch eine Null terminiert werden und das ist hier einfach nicht der Fall, deshalb wird mehr ausgegeben als eigentlich im String steht (bis zur nächsten 0 im RAM).

Sprich, er kann auch einfach vor wcstombs ZeroMemory(charbuffer, wcslen(buffer)+1); schreiben, doch wie ich bereits sagte, die C++ Variante ist um Welten lesbarer als dieser kryptische Mist.

C++ kann so schön sein, wenn man es denn auch nutzt.
Doch, std::string hätte dasselbe Problem. Wenn im Speicher eine 0 fehlt, dann wird bei deinem std::wstring wstr = nastyPtr der Fehler ebenso eintreten.

Das soll nicht heißen, dass ich dir nicht Recht gebe, der C++ Weg ist trotzdem um einiges schöner.
07/05/2012 23:18 Nightblizard#7
Achso, ja klar! Wenn die 0 fehlt, dann funktioniert das natürlich nicht. Da habe ich dich falsch verstanden, tut mir leid.

@Coxxy:
Wenn schon C, dann auch richtig. Dieses C/C++ Gemische führt in unerfahrenen Händen (hier z.B.) zu explosiven Code. Vertraut in C++ der STL, das macht das Leben wesentlich leichter!
07/05/2012 23:43 Dr. Coxxy#8
statt new malloc, ich sehe jedoch kein problem darin, new zu benutzen.

dein "tipp" mit ZeroMemory ist übrigens unnötig, es reicht wcstombs stringlen auch das 0 zeichen mitzugeben.

EDIT:
ich behaupte außerdem einfach mal, dass diese methode um einiges schneller als deine c++ methode ist, habs zwar nicht ausprobiert, sollte aber so sein, auch wenn ich die implementierung von wcstombs natürlich nicht kenne.