c++ - const unsigned char*to std:: string
strlen (9)
sqlite3_column_text devuelve un const unsigned char *, ¿cómo convierto esto a std :: string? He intentado std :: string (), pero me sale un error.
Código:
temp_doc.uuid = std::string(sqlite3_column_text(this->stmts.read_documents, 0));
Error:
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
En caso de que realmente desee una cadena de caracteres sin firmar, puede crear su propio tipo:
typedef std::basic_string <unsigned char> ustring;
Debería poder decir cosas como:
ustring s = sqlite3_column_text(this->stmts.read_documents, 0);
La razón por la que las personas suelen utilizar un tipo (sin signo char *) es para indicar que los datos son binarios y no simples en texto ASCII. Sé que libxml hace esto, y por lo que parece, sqlite está haciendo lo mismo.
Los datos que está obteniendo de la llamada sqlite probablemente sean texto Unicode codificado en UTF-8. Mientras que un reinterpret_cast puede parecer que funciona, si alguna vez alguien almacena texto en el campo que no es ASCII simple, su programa probablemente no se comportará bien.
La clase std :: string no está diseñada con Unicode en mente, así que si pides la longitud () de una cadena, obtendrás el número de bytes, lo cual, en UTF-8, no es necesariamente lo mismo como la cantidad de personajes.
Respuesta corta: el elenco simple puede funcionar, si está seguro de que los datos son solo ASCII. Si puede ser cualquier dato UTF-8, entonces necesita manejar la codificación / decodificación de una manera más inteligente.
No estoy familiarizado con sqlite3_column_text, pero una cosa que querrás hacer es cuando llamas al constructor std: string, querrás lanzar a (const char *). Creo que debería tener un constructor para ese tipo.
Sin embargo, es extraño que esta función sqlite sea return an unsigned char *, ¿está devolviendo una cadena Pascal (la primera char es la longitud de la cadena)? Si es así, entonces tendrá que crear std :: string con los bytes y la longitud.
No puede construir una std::string
desde c onst unsigned char*
- tiene que convertirlo a const char*
primero:
temp_doc.uuid = std::string( reinterpret_cast< const char* >(
sqlite3_column_text(this->stmts.read_documents, 0) ) );
No soy un experto, pero este ejemplo aquí parece mucho más simple:
string name = (const char*) (sqlite3_column_text(res, 0));
Tu podrías intentar:
temp_doc.uuid = std::string(reinterpret_cast<const char*>(
sqlite3_column_text(this->stmts.read_documents, 0)
));
Mientras std::string
podría tener un constructor que toma const unsigned char*
, aparentemente no es así.
¿Por qué no, entonces? Podrías echarle un vistazo a esta pregunta algo relacionada: ¿Por qué las transmisiones en C ++ usan char en lugar de char sin signo?
Una pregunta antigua pero importante, si tiene que conservar la información completa en la secuencia de caracteres sin firmar. En mi opinión eso es con reinterpret_cast no es el caso. Encontré una solución interesante en la conversión de cadena a vector que modifiqué para
basic_string<unsigned char> temp = sqlite3_column_text(stmt, 0);
string firstItem( temp.begin(), temp.end() );
Dado que estoy programando para gtkmm, puede realizar la conversión a una conexión estándar de
basic_string<unsigned char> temp = sqlite3_column_text(stmt, 0);
Glib::ustring firstItem = string( temp.begin(), temp.end() );
si temp_doc.uuid es una std :: cadena, intente:
temp_doc.uuid = static_cast<const char*>(sqlite3_column_text(this->stmts.read_documents, 0));
tratar:
temp_doc.uuid = std::string(reinterpret_cast<const char*>(sqlite3_column_text(this->stmts.read_documents, 0)));