2009-02-02 3 views
15

Je travaille dans un projet non géré C++.Récupère les octets de std :: string en C++

J'ai besoin de savoir comment puis-je prendre une chaîne comme celle-ci "certaines données à chiffrer" et obtenir un tableau d'octets [] que je vais utiliser comme source pour chiffrer.

En C# je fais

for (int i = 0; i < text.Length; i++) 
    buffer[i] = (byte)text[i]; 

Ce que je dois savoir est comment faire la même chose mais en utilisant C++ non géré.

Merci!

+0

évidemment c'est sur C++. J'ai corrigé les fautes de frappe –

+0

ouais tu as raison, merci – Vic

Répondre

24

Si vous avez juste besoin d'un accès en lecture seule, puis c_str() le fera:

char const *c = myString.c_str(); 

Si vous avez besoin d'un accès en lecture/écriture, vous pouvez copier la chaîne dans un vecteur. les vecteurs gèrent la mémoire dynamique pour vous. Vous ne devez pas jouer avec l'allocation/désallocation alors:

std::vector<char> bytes(myString.begin(), myString.end()); 
bytes.push_back('\0'); 
char *c = &bytes[0]; 
+1

S'il veut un tableau d'octets a-t-il besoin de la fin '\ 0'? Dans ce cas, vous pouvez utiliser data() en lecture seule. –

+0

je n'étais pas sûr s'il a besoin du \ 0 ou pas. S'il ne le sait pas, il sait maintenant qu'il peut utiliser .data(). Merci d'avoir commenté cela, Martin. –

+1

Cette réponse semble correcte et peut fonctionner mais en supposant que le stockage de données pour un vecteur de caractère est contigu et ne change pas est dangereux. – Mark

1

D'un std :: string, vous pouvez utiliser la méthode c_ptr() si vous voulez obtenir au pointeur de la mémoire tampon de char_t.

Il semble que vous vouliez simplement copier les caractères de la chaîne dans un nouveau tampon. Je voudrais simplement utiliser la fonction std::string::copy:

length = str.copy(buffer, str.size()); 
+0

Certaines implémentations de std :: string peuvent utiliser le comptage de références, de sorte qu'une copie n'entraîne pas nécessairement de nouveaux octets pouvant être écrêtés en toute sécurité. –

0

Si c'est juste C plain vanilla, puis:

strcpy(buffer, text.c_str()); 

En supposant que le tampon est alloué et assez grand pour contenir le contenu du « texte », qui est l'hypothèse dans votre code d'origine.

Si Crypter() prend un « const char * », vous pouvez utiliser

encrypt(text.c_str()) 

et vous n'avez pas besoin de copier la chaîne.

3

Normalement, les fonctions de cryptage prennent

encrypt(const void *ptr, size_t bufferSize); 

comme arguments. Vous pouvez transmettre c_str et la longueur directement:

encrypt(strng.c_str(), strng.length()); 

De cette façon, de l'espace supplémentaire est alloué ou gaspillé.

+0

Si vous passez un pointeur et une longueur, alors vous devriez utiliser data() plutôt que c_str() pour indiquer qu'il n'est pas utilisé comme une chaîne. –

18

std::string::data semble être suffisant et le plus efficace. Si vous voulez avoir une mémoire non-const à manipuler (étrange pour le chiffrement), vous pouvez copier les données vers un tampon à l'aide memcpy:

unsigned char buffer[mystring.length()]; 
memcpy(buffer, mystring.data(), mystring.length()); 

STL fanboys vous encourage à utiliser std::copy à la place:

std::copy(mystring.begin(), mystring.end(), buffer); 

mais il n'y a vraiment pas grand-chose à cet égard. Si vous avez besoin d'une terminaison nulle, utilisez std::string::c_str() et les diverses techniques de duplication de chaînes que d'autres ont fournies, mais j'éviterais généralement cela et demanderais simplement le length.Particulièrement avec la cryptographie, vous savez juste que quelqu'un va essayer de le casser en y insérant des zéros, et en utilisant std::string::data() vous décourage de faire paresseusement des suppositions sur les bits sous-jacents dans la chaîne.

1

Si vous avez juste besoin de lire les données.

encrypt(str.data(),str.size()); 

Si vous avez besoin d'une copie en lecture/écriture des données, placez-la dans un vecteur. (Don; t allouer dynamiquement l'espace qui est le travail de vecteur).

std::vector<byte> source(str.begin(),str.end()); 
encrypt(&source[0],source.size()); 

Bien sûr, nous supposons tous que l'octet est un caractère !!!

-6

Je ne pense pas que vous voulez utiliser le code C# que vous avez là. Ils fournissent System.Text.Encoding.ASCII (également UTF- *)

string str = "some text; 
byte[] bytes = System.Text.Encoding.ASCII.GetBytes(str); 

vos problèmes proviennent d'ignorer l'encodage en C# pas votre code C++

Questions connexes