2009-04-29 9 views
32

sqlite3_column_text renvoie un caractère const non signé *, comment puis-je le convertir en std :: string? J'ai essayé std :: string(), mais j'ai une erreur.const unsigned char * à std :: string

code:

temp_doc.uuid = std::string(sqlite3_column_text(this->stmts.read_documents, 0)); 

Erreur:

1>.\storage_manager.cpp(109) : error C2440: '<function-style-cast>' : cannot convert from 'const unsigned char *' to 'std::string' 
1>  No constructor could take the source type, or constructor overload resolution was ambiguous 

Répondre

39

Vous pouvez essayer:

temp_doc.uuid = std::string(reinterpret_cast<const char*>(
     sqlite3_column_text(this->stmts.read_documents, 0) 
)); 

Alors que std::string pourrait avoir un constructeur qui prend const unsigned char*, semble-t-il pas. Pourquoi pas, alors? Vous pouvez jeter un oeil à cette question quelque peu liée: Why do C++ streams use char instead of unsigned char?

+1

+1. Cependant, je pense que vous devriez faire ce "const char *" à l'intérieur de vos chevrons. Vous ne voulez pas essayer de rejeter la constance (qu'elle ne peut même pas permettre). – rmeador

+0

Très vrai! Merci pour la remarque. – Reunanen

+0

Je reçois cette erreur: 1>. \ Storage_manager.cpp (109): erreur C2440: 'static_cast': impossible de convertir 'const unsigned char *' en 'const char *' 1> Les types pointés ne sont pas liés; la conversion nécessite une distribution reinterpret_cast, une distribution de type C ou une distribution de type fonction –

4

Je ne suis pas familier avec sqlite3_column_text, mais une chose que vous voudrez peut-être faire est quand vous appelez le constructeur std: string, vous voudrez lancer vers (const char *). Je crois qu'il devrait avoir un constructeur pour ce type.

Cependant, il est étrange que cette fonction sqlite renvoie un caractère non signé *, renvoie-t-il une chaîne Pascal (le premier caractère est la longueur de la chaîne)? Si c'est le cas, vous devrez créer la chaîne std :: avec les octets et la longueur.

+0

Non, ils ont une terminaison nulle. – Navin

2

Vous ne pouvez pas construire un std::string de c onst unsigned char* - vous devez le jeter aux const char* première:

temp_doc.uuid = std::string(reinterpret_cast< const char* >(
    sqlite3_column_text(this->stmts.read_documents, 0))); 
+0

Donc - il n'y a pas moyen du tout? –

+0

Désolé, vous devez utiliser reinterpret_cast au lieu de static_cast. – Kasprzol

2

si temp_doc.uuid est un std :: string essayer:

temp_doc.uuid = static_cast<const char*>(sqlite3_column_text(this->stmts.read_documents, 0)); 
+0

C'est une std :: string, et en essayant votre méthode me donne: 1>. \ Storage_manager.cpp (109): erreur C2440: 'static_cast': impossible de convertir 'const unsigned char *' en 'const char * ' 1> Les types pointés ne sont pas liés; conversion nécessite reinterpret_cast, cast de style C ou cast de fonction –

3

essayer:

temp_doc.uuid = std::string(reinterpret_cast<const char*>(sqlite3_column_text(this->stmts.read_documents, 0))); 
+0

J'ai vu quelqu'un déjà posté la réponse, j'ai commencé à écrire cette réponse avant que l'autre soit postée (vérifiait que la réponse est correcte dans VS) – user88637

+0

Merci! Cela a fonctionné - mais pourquoi avez-vous besoin de le faire de cette façon? –

+0

Je dis seulement que je ne pense pas que je copie des réponses – user88637

17

Sur le hasard, vous voulez vraiment une chaîne de uni caractères ci a été conçu, vous pouvez créer votre propre type:

typedef std::basic_string <unsigned char> ustring; 

Vous devriez alors être en mesure de dire des choses comme:

ustring s = sqlite3_column_text(this->stmts.read_documents, 0); 
12

La raison que les gens utilisent généralement un type (non signé char *) est d'indiquer que les données sont binaires et non en texte ASCII. Je sais que libxml fait ça, et d'après ce que ça donne, sqlite fait la même chose.

Les données que vous récupérez de l'appel sqlite sont probablement du texte Unicode codé en UTF-8. Alors qu'un reinterpret_cast peut sembler fonctionner, si quelqu'un stocke du texte dans le champ qui n'est pas ASCII, votre programme ne sera probablement pas bien comporté. La classe std :: string n'est pas conçue en pensant à Unicode, donc si vous demandez la longueur() d'une chaîne, vous obtiendrez le nombre d'octets qui, en UTF-8, n'est pas nécessairement la même chose que le nombre de caractères. Réponse courte: la distribution simple peut fonctionner, si vous êtes certain que les données sont simplement ASCII. S'il peut y avoir des données UTF-8, vous devez gérer l'encodage/décodage de façon plus intelligente.

+1

Y a-t-il un moyen de le faire avec la bibliothèque std :: library? –

+0

Pas que je sache. L'approche standard consiste à utiliser une bibliothèque tierce, par exemple: http://site.icu-project.org/ –

2

Je ne suis pas expert, mais cet exemple semble ici beaucoup plus simple:

string name = (const char*) (sqlite3_column_text(res, 0)); 
Questions connexes