Frage

Ich habe die folgende Zeichenfolge:

index                                       0   1   2   3   4   5   6   7
std::string myString with the content of "\xff\xff\xff\x00\xff\x0d\x0a\xf5"

Wenn ich auf myString beziehen [3], ich den erwarteten '\ x00' Wert.

Aber wenn ich auf myString Bezug [5], ich zwei Werte erhalten "\ x0d \ x0a" statt nur '\ x0d'.

Noch interessanter ist der myString [6] Wert, der das '\ xf5' ist. Dieses Mal ist es wie die \ x0d nicht existierte und die richtige Position verwiesen wurde.

Meine Frage wäre: Was ist so besonders über die \ x0d Zeichen in einem std: string-Objekt? Wie kommt es übersprungen, wenn die Indizierung? Es ist wie auf diese Weise zu zählen:

index                     0   1   2   3   4   5   5   6
std::string myString = "\xff\xff\xff\x00\xff\x0d\x0a\xf5"

Als Kommentar, der '\ x0d' Zeichen ist das 13. ASCII-Zeichen "Carriage Return" und '\ x0a' ist der Zeilenvorschub.

UPDATE: Kann es, dass std :: string hält "\ x0d \ x0a" als ein einzelnes Zeichen und belegt damit nur eine Position in der Kette? Ist der '\ x0d' ein "Geheimnis" Charakter in Bezug auf std :: string?

WEITERE INFORMATIONEN: http://en.wikipedia.org/wiki/Newline

War es hilfreich?

Lösung

Sind Sie sicher, dies geschieht mit std::string? std::string::operator[] gibt einen const char &, so wie es zwei Zeichen zurückkehren ('\x0d' und '\x0a')?

sagte, dass ist in der Regel "\x0d\x0a" für Zeilenenden unter Windows verwendet, während nur '\x0a' unter Linux verwendet wird, so Umwandlung des ersteren zum letzteren relativ häufig unter Windows ist - zum Beispiel, ich denke an das Verhalten von fopen, wenn sie mit "wt" genannt. Ich würde vermuten, etwas Ähnliches mit Ihnen geschieht.

Bearbeiten : Auf der Basis Ihrer Kommentare auf die ursprüngliche Frage, ich glaube, ich kann mir denken, was los ist

.

Ich glaube, dass die Zeichenfolge nicht wirklich enthalten, was Sie denken, es enthält. Sie sind die Irre geführt werden, weil der Mechanismus Sie die Zeichenfolge in einer Datei Ausgabe mit sind (wahrscheinlich ofstream?) End-of-line Übersetzung ausführt. Dies bedeutet, dass ein '\n' (der Unix-end-of-line-Code) (der Windows-end-of-line-Code) '\r\n' übersetzt. Der Zweck der End-of-line Übersetzung ist Code mehr tragbar zwischen den Betriebssystemen zu machen. Sie können es verhindern, indem Sie die Datei in Binär-Modus zu öffnen ; für ofstream wird dies durch die Angabe der ios_base::binary Flagge gemacht, wenn Sie die Datei öffnen, aber dieser Flag ist standardmäßig nicht gesetzt.

(Siehe diesen Wikipedia-Artikel für weitere Informationen über End-of-line Markierungen auf verschiedenes Betriebssysteme.)

Das ist, was ich glaube los ist. Ihre Zeichenfolge enthält tatsächlich

index                 0   1   2   3   4   5   6
myString contents  "\xff\xff\xff\x00\xff\x0a\xf5"

Du ausgibt es so etwas wie folgt aus:

ofstream file("myfile.txt");
for(size_t i=0; i<myString.size(); i++)
    ofstream << myString[i];

Aufgrund der End-of-line Übersetzung expalined oben wird die '\x0a' in myString[5] als '\x0d\x0a' ausgegeben wird, und das ist, was Sie ist verwirrend.

Andere Tipps

Eine Sache, die falsch hier los ist ist die folgende Zeile nicht tut, was Sie erwarten:

std::string myString = "\xff\xff\xff\x00\xff\x0d\x0a\xf5";

Dies ruft den std::string(const char *) Konstruktor, der einen C-Stil nullterminierten String in einem C ++ std::string konvertiert ausgelegt ist. Dieser Konstruktor liest Bytes an dem angegebenen Zeiger und kopiert sich auf den neuen std::string beginnen, bis es einen Null-Byte (\ x00) erreicht. Dies steht im Einklang mit dem Verhalten von C-Funktionen wie strlen().

Also, wenn Ihr myString aufgebaut ist, besteht es aus einem String der Länge 3, mit Bytes \ xff, \ xff, \ xff. Der Zugriff auf Indizes größer als 2 sind Bytes vom Ende des Feldes zugreift (die einen Laufzeitfehler im besten Fall erzeugen wird, oder nicht definiertes Verhalten im schlimmsten Fall).

Beachten Sie, dass ein std::string Zwischennullbytes halten kann, aber Sie kann nicht die oben Konstruktor verwenden, wie eine Zeichenfolge zu initialisieren, da die Null-Byte als die Einstellung des C-String an den Konstruktor übergeben interpretiert wird.

Es würde sich lohnen, Ihren Code wieder mit dem \ x00 Byte versuchen, auf etwas anderes geändert, nur um zu sehen, wie es unterscheidet sich von dem, was Sie bereits beschrieben haben:

std::string myString = "\xff\xff\xff\x01\xff\x0d\x0a\xf5"

Überprüfen Sie auch myString.length() nach dem obigen Konstruktor, um zu sehen, was Sie erhalten.

Sie erstellen Zeichenfolge mit folgenden Konstruktor: string(char const *)

Es empfängt NUL C-String beendet. So findet es seine Länge nach den ersten 0-Zeichen.

Sie sollten andere Konstruktor verwenden, der angibt, Größe: string(char const *,size_t n) durch den Aufruf:

std::string myString("\xff\xff\xff\x00\xff\x0d\x0a\xf5",8);

Siehe http://www.cplusplus.com/reference/string/string / string / zur weiteren Lektüre

Sie sind wahrscheinlich zu mißbrauchen des Operators [].

Der Operator [] liefert einen const char. Allerdings sind Sie wahrscheinlich dies als Zeiger verwenden und somit zwei Zeichen bekommen -. Wir müssen Ihren eigentlichen Code zu sehen, dies zu bestätigen

0x00 ist ein Null-Terminator für ein c-string, so dass wahrscheinlich ist, warum Sie nur ein (richtige) Zeichen dafür zu bekommen.

Was passiert, wenn Sie erhalten [4]?

In Visual Studio 2008 wird die \ x00 das Ende der Zeichenfolge betrachtet. So myString.lenght 3. kehrt Wenn Sie den Zugriff auf myString versuchen [5] erhalten Sie einen Fehler.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top