Domanda

Ho la seguente stringa:

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

Quando sto riferendosi a myString [3], ho la '\ x00' valore atteso.

Ma quando mi riferisco a myString [5], ottengo due valori "\ x0d \ x0a" invece di '\ x0d'.

Ancora più interessante è la [6] Valore Stringa, che è il '\ XF5'. Questa volta è come la \ x0d non esisteva e la posizione corretta è stato fatto riferimento.

La mia domanda sarebbe: che cosa c'è di così speciale il carattere x0d \ in uno std: oggetto stringa? Come mai è saltata per l'indicizzazione? E 'come contare in questo modo:

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

Come commento, il carattere '\ x0d' è il carattere ASCII 13 "carriage return" e '\ x0a' è il carattere di avanzamento riga.

UPDATE: Può essere che std :: string considera "\ x0d \ x0a" come un singolo carattere e occupa quindi una sola posizione nella stringa? E 'questo '\ x0d' un personaggio "mistero" per quanto riguarda std :: string?

Informazione supplementare: http://en.wikipedia.org/wiki/Newline

È stato utile?

Soluzione

Sei sicuro che questo sta accadendo con std::string? std::string::operator[] restituisce un const char &, così come può essere tornando due caratteri ('\x0d' e '\x0a')?

Detto questo, "\x0d\x0a" è di solito utilizzato per la fine riga sotto Windows, mentre solo '\x0a' viene utilizzato sotto Linux, in modo da conversione della prima alla seconda è relativamente comune in ambiente Windows - per esempio, sto pensando di comportamento di fopen quando viene chiamato con "wt". Direi qualcosa di simile sta accadendo a te.

Modifica : In base alle vostre osservazioni sulla domanda iniziale, credo di poter immaginare quello che sta succedendo

.

Credo che la stringa in realtà non contiene ciò che si pensa che contiene. Stai essere ingannati perché il meccanismo si sta utilizzando per l'uscita la stringa in un file (probabilmente ofstream?) Sta eseguendo traduzione end-of-line. Ciò significa che una '\n' (il codice Unix fine riga) è tradotta in '\r\n' (codice di Windows end-of-line). Lo scopo della traduzione di fine linea è di rendere il codice più portabile tra sistemi operativi. È possibile inibire aprendo il file in modalità binaria ; per ofstream, questo è fatto specificando il flag ios_base::binary quando si apre il file, ma questo flag non è impostato di default.

(Vedi questa Wikipedia articolo per ulteriori informazioni sui marcatori end-of-line su diversi i sistemi operativi).

Questo è quello che io credo che sta accadendo. La stringa contiene in realtà

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

Si sta output è qualcosa di simile:

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

A causa della traduzione end-of-line expalined sopra, la '\x0a' in myString[5] è essere uscita come '\x0d\x0a', e questo è ciò che è fonte di confusione voi.

Altri suggerimenti

Una cosa che sta andando male qui è la seguente linea non fa quello che ti aspetti:

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

Questo chiama il costruttore std::string(const char *), che è stato progettato per convertire una stringa con terminazione null C-stile a un std::string C ++. Questo costruttore legge byte a partire dalla data del puntatore e li copia alla nuova std::string fino a raggiungere un byte null (\ X00). Questo è coerente con il comportamento di funzioni C come strlen().

Così, quando il vostro myString è costruito, si compone di una stringa di lunghezza 3, con byte \ xff, \ xff, \ XFF. Accesso agli indici maggiori di 2 byte accedono l'estremità della matrice (che produrrà un errore in esecuzione al meglio, o comportamento indefinito nel peggiore dei casi).

Si noti che un std::string può contenere byte nulli intermedi, ma può non utilizzare il costruttore sopra per inizializzare un tale stringa perché il byte null viene interpretato come terminare la stringa in stile C passata al costruttore.

Sarebbe la pena di provare di nuovo il codice con il byte \ x00 cambiato in qualcosa di diverso, solo per vedere come si differenzia da quello che hai già descritti:

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

Inoltre, controllare myString.length() dopo il costruttore sopra per vedere quello che si ottiene.

Si crea stringa con seguente costruttore: string(char const *)

Riceve NUL stringa terminata C. Così trova la sua lunghezza in base al primo carattere 0.

Si dovrebbe usare altro costruttore che specifica dimensione: string(char const *,size_t n) chiamando:

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

http://www.cplusplus.com/reference/string/string / string / per ulteriori lettura

Probabilmente si sta abusando l'operatore [].

L'operatore [] restituisce un const char. Tuttavia probabilmente si sta utilizzando questo come un puntatore e ottenere così due personaggi -. Abbiamo bisogno di vedere il codice vero e proprio per confermare questo

0x00 è un null-terminazione per un c-stringa in modo che è probabilmente il motivo che si stanno ottenendo solo un carattere (corretta) per questo.

Che cosa succede quando si ottiene [4]?

In Visual Studio 2008, il \ x00 è considerato il fine della stringa. Così myString.lenght ritorna 3. Quando si tenta di accedere myString [5] si ottiene un errore.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top