2015-09-25 11 views
5

Ho variabile std :: string. E ho bisogno di mettere alcuni byte dalla serie di caratteri non firmati ad esso. Conosco il primo byte e il numero.Metti byte da unsigned char array a std :: string usando la funzione memcpy()

Posso usare la funzione std :: string :: assign. L'ho fatto.

Ma voglio risolvere quel problema in modo corretto utilizzando la funzione memcpy.

std::string newString; 
memcpy(&newString, &bytes[startIndex], length); 

So che è sbagliato. Ho ricercato e trovato alcune idee usando std :: vector.

Please help me per trovare la soluzione più elegante per questo problema.

+4

Perché pensi che "assign()" non sia la "giusta"? – Barry

+0

"nel modo giusto" è "So che è sbagliato" =? – crashmstr

+0

@Barry Voglio risolverlo in due modi diversi. Sto imparando il linguaggio C++. E trovare questa soluzione è interessante per me :) –

risposta

11

Dal momento che siamo solo la costruzione della stri ng, v'è un costruttore std::string che prende due iteratori:

template< class InputIt > 
basic_string(InputIt first, InputIt last, 
       const Allocator& alloc = Allocator()); 

che possiamo fornire:

std::string newString(&bytes[startIndex], &bytes[startIndex] + length); 

Se non stiamo costruendo la stringa e siamo invece di assegnare ad uno già esistente, si dovrebbe preferisco ancora usare assign(). Questo è esattamente ciò che la funzione è per:

oldString.assign(&bytes[startIndex], &bytes[startIndex] + length); 

Ma se davvero ostini a memcpy() per qualche ragione, allora avete bisogno di fare in modo che la stringa in realtà ha dati sufficienti per essere copiati in. E poi basta copiarlo usando &str[0] come indirizzo di destinazione e dagger;:

oldString.resize(length); // make sure we have enough space! 
memcpy(&oldString[0], &bytes[startIndex], length); 

& pugnale; Pre-C++ 11 non è tecnicamente garantito che le stringhe siano memorizzate in memoria in modo contiguo, sebbene in pratica ciò sia avvenuto comunque.

+1

Perché il downvote? – Barry

+0

IDK. sembra che a qualcuno non piacesse nessuna delle risposte – NathanOliver

+0

Penso che '& bytes [startIndex + length]' sarebbe più coerente con quello che hai (nessun aritmetico del puntatore eseguito dal programmatore). Ma c'è anche il codificatore di stringhe che prende un 'const char *' e una lunghezza: 'std :: string newString (& byte [startIndex], lunghezza);' –

-1

è necessario impostare la dimensione della stringa in modo che non ci sarà un buffer di dimensioni adeguate per ricevere i dati, e il cast del constness fuori del puntatore si ottiene da data()

std::string newString; 
newString.resize(length); 
memcpy((char*)newString.data(), &bytes[startIndex], length); 

naturalmente tutti questo è nel regno di un comportamento indefinito, ma non meno standard.

+0

Into '& newString'? – Barry

+0

hai ragione, corretto – shoosh

-3

Si tratta di un hack e come hai detto modo sbagliato, ma è possibile, in quanto garantisce STL che std::string ha stoccaggio contigue:

std::string str(32, '\0'); 
std::strcpy(const_cast<char*>(str.data()), "REALLY DUDE, IT'S ILLEGAL WAY"); 

Naturalmente, è possibile utilizzare std::memcpy nello stesso modo (io ho usato strcpy solo copia terminazione null string) ...

Nel tuo caso:

str.resize(length); 
memcpy(const_cast<char*>(str.data()), bytes + startIndex, length); 
+0

E se la stringa che stai copiando ha più di 32 byte? – Barry

+0

Ovviamente, dovresti "preimpostare" una stringa ben adattata (attenzione, 'ridimensiona()' non 'reserve()'!) – Nevermore

+2

per chiarire cosa significhi mai più per "modo illegale": [* Modifica dell'array di caratteri a cui si accede tramite i dati è un comportamento non definito *] (http://en.cppreference.com/w/cpp/string/basic_string/data). Non fare questo –