0x00 und char-arrays
Warum char-arrays halten direkt vor einem 0x00-byte erkannt wird und wie kann dieses problem vermieden werden (vielleicht durch ein mit einem anderen Datentyp (welche und warum) oder einen "trick" mit dem char)?
Zum Beispiel in dem folgenden code, wird der Ausgang "a" nur die anderen bytes werden nicht angezeigt:
unsigned char cbuffer[]={0x61,0x00,0x62,0x63,0x0};
std::string sbuffer=reinterpret_cast<const char*>(cbuffer);
cout << sbuffer << endl;
Ähnlich wie im folgenden code, wird der Ausgang "ab":
unsigned char cbuffer[]={0x61,0x62,0x00,0x63,0x0};
std::string sbuffer=reinterpret_cast<const char*>(cbuffer);
Einfache und wirksame Abhilfen, um das problem (wo 0x00 gehalten wird, in das array wie eine normale byte) würde geschätzt.
- Ähmm. Weil strings in C sind arrays von char beendet mit einem null-byte?
- std::vector mit überladenen
operator << (ostream&, const vector<char>&)
. - Nicht unbedingt. Es ist nicht ungewöhnlich, nicht zu verwenden, nachfolgende Nullen. Die Sprache selbst nur erfordert es für string-Literale. Die Bibliotheken können auch verlangen, aber das ist nicht das gleiche.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ist es üblich, in C zu übergeben, um strings als Zeiger auf null-terminierte
char
arrays. null wird vertreten durch0x00
. Um die Konvertierung einfach, diestd::string
ist constructable von einem Zeiger auf eine null-terminierte char-array, das ist, was passiert mit Ihrem code. Aber wenn es findet, der null ist, er denkt, dass das das Ende der Zeichenfolge. Wenn Siecout
ein char-array direkt, Sie werden feststellen, es macht die gleiche Annahme, weil Sie keinen anderen Weg, um zu bestimmen, das Ende der Zeichenkette gezeigt, durch einechar*
. (Sie könnte theoretisch sagen, die Länge ist in Ihrem Fall, wenn Sie verstehenchar (&)[]
, aber fast nichts in die standard-Bibliothek bietet leider).Den beabsichtigten Problemumgehungen verwenden Sie diesen Konstruktor, stattdessen:
oder
Aber Sie müssen vorsichtig sein, mit
sizeof(cbuffer)
. Wenncbuffer
ist einchar*
(Zeiger) statt einerchar(&)[]
(array), dannsizeof(ptr)
wird es wieder den falschen Wert, und es gibt keinen Weg, um die richtige Länge an diesem Punkt, wenn der string nicht null-terminiert ist.sizeof
zu bestimmen, die Länge des Puffers.char-arrays nicht alles tun,
Die C-string-Funktionen verwenden 0 zu markieren das Ende einer Zeichenkette.
std::cout überlastet ist für char-arrays zu drucken, die Sie als 'c' - Saiten, wenn Sie drucken möchten, die einzelnen Werte müssen Sie eine Schleife über die Werte, vielleicht wollen Sie auch ausgegeben werden als std::hex
In diesem Fall erstellen Sie einen std::String durch ein 'c' char-array, also der ctor von std::string wird davon ausgegangen, dass die 'c' - Saiten-Ende auf " 0 " stehen. Da es nur an eine Adresse im Speicher, wie sonst kann er wissen, wo der string zu Ende ist?
ps. Wenn Sie speichern möchten, die ein array von bytes ist, sollten Sie wahrscheinlich mit std::vector
System::String
cout
ein char-array, ercout
s astd::string
Objekt, die nicht dieses Problem haben.Versuchen:
Dem 0x00-byte wird als sentinel zu markieren das Ende des Strings in C. Das gesamte array bleibt jedoch im Speicher. Sie können einen alternativen Konstruktor für
std::string
wenn Sie möchten, dass die Zeichenfolge, enthalten Sie die gesamte Zeichen-array. Aber den Druck, der string wäre immer noch geben Ihnen nur "ab". Diese Entscheidung zu vertreten, C-strings in dieser Weise ist einer dieser beliebige Entscheidungen, dass wir stecken geblieben sind, mit.0x00 ist eine non-print-Zeichen, 0..0x20, sind alle non-print
char
s obwohl einige dienen als Zeilenumbrüche. 0x00 dient zum beenden eine Zeichenkette.Was willst du werden ersetzt (und gedruckt) für 0x00 im string?
Konstruktor ist verantwortlich für die Konvertierung von char[] in einen string.
Wie andere hingewiesen, die Sie verwenden müssen, verschiedene Konstruktor. Der code unten ist für mich zu arbeiten, aber es ist nicht sehr roboust. Der erste parameter muss ein Zeiger auf den array - (Sie sind frei zu verwenden, sicherer Gießen) und der zweite parameter ist die Länge des Arrays (sind Sie frei, um zu berechnen, dies in einer mehr
anspruchsvolle Art und Weise).