2009-04-29 30 views
32

sqlite3_column_text zwraca const unsigned char *, w jaki sposób mogę przekonwertować to na std :: string? Próbowałem już std :: string(), ale pojawia się błąd.const unsigned char * na std :: string

Kod:

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

Błąd:

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 

Odpowiedz

39

można spróbować:

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

Podczas std::string może mieć konstruktor, że trwa const unsigned char*, najwyraźniej nie.

Dlaczego nie, więc? Możesz rzucić okiem na to nieco powiązane pytanie: Why do C++ streams use char instead of unsigned char?

+1

+1. chociaż myślę, że powinieneś zrobić to "const char *" w swoich nawiasach ostrych. Nie chcesz próbować odrzucić konstelacji (na co może nawet nie pozwolić). – rmeador

+0

Bardzo prawdziwe! Dzięki za uwagę. – Reunanen

+0

Otrzymuję ten błąd: 1>. \ Storage_manager.cpp (109): błąd C2440: "static_cast": nie można przekonwertować z "const unsigned char *" na "const char *" 1> Wskazane typy nie są powiązane; Konwersja wymaga reinterpret_cast, obsady stylu C lub obsady stylu. –

4

Nie jestem zaznajomiony z sqlite3_column_text, ale jedną rzeczą, którą możesz chcieć zrobić, kiedy wywołujesz konstruktor std: string, będziesz chciał rzucić (const char *). Uważam, że powinien on mieć konstruktora dla tego typu.

Jednak jest dziwne, że ta funkcja sqlite zwraca niepodpisany znak *, czy zwraca ciąg Pascala (pierwszy znak jest długością łańcucha)? Jeśli tak, to musisz utworzyć ciąg std :: string z bajtami i długość.

+0

Nie, są one zakończone. – Navin

2

Nie można skonstruować std::string od c onst unsigned char* - trzeba oddać go do const char* pierwszy:

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

A więc - w ogóle nie ma mowy? –

+0

Niestety, musisz użyć reinterpret_cast zamiast static_cast. – Kasprzol

2

jeśli temp_doc.uuid to try std :: string:

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

To jest std :: string, a wypróbowanie twojej metody daje mi: 1>. \ Storage_manager.cpp (109): błąd C2440: 'static_cast': nie można przekonwertować z 'const unsigned char *' na 'const char * ' 1> Wskazane typy nie są ze sobą powiązane; Konwersja wymaga reinterpret_cast, rzutowania w stylu C lub stylu obsady –

3

spróbuj:

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

Widziałem, że ktoś już opublikował odpowiedź, zacząłem pisać tę odpowiedź, zanim druga została wysłana (sprawdził, że odpowiedź jest poprawna w VS). – user88637

+0

Dzięki! Udało się - ale dlaczego musisz to robić w ten sposób? –

+0

Mówię tylko to, więc nie będę myślał, że kopiuję odpowiedzi – user88637

17

W przypadku braku szansy, w rzeczywistości potrzebujesz ciągu unsi znaków gned, można utworzyć własny typ:

typedef std::basic_string <unsigned char> ustring; 

Należy wtedy w stanie powiedzieć takie rzeczy jak:

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

Powodem ludzie zwykle używać (unsigned char *) typ jest wskazanie, że dane są binarne, a nie zwykły tekst ASCII. Wiem, że libxml robi to, i od tego wyglądu, sqlite robi to samo.

Dane, które otrzymujesz z połączenia sqlite, to prawdopodobnie kodowanie Unicode w formacie UTF-8. Chociaż może się wydawać, że reinterpret_cast działa, jeśli ktoś kiedykolwiek zapisuje tekst w polu, które nie jest prostym ASCII, Twój program prawdopodobnie nie będzie dobrze zachowany.

Klasa std :: string nie jest zaprojektowana z myślą o Unicode, więc jeśli poprosisz o długość() ciągu, otrzymasz liczbę bajtów, która w UTF-8 nie jest koniecznie to samo, co liczba znaków.

Krótka odpowiedź: prosta obsada może działać, jeśli masz pewność, że dane są po prostu ASCII. Jeśli mogą to być dane w formacie UTF-8, musisz w inteligentniejszy sposób obsługiwać kodowanie/dekodowanie.

+1

Czy jest sposób na zrobienie tego z biblioteką std :: library? –

+0

Nie to, co wiem. Standardowe podejście polega na użyciu biblioteki innej firmy, na przykład: http://site.icu-project.org/ –

2

Nie jestem ekspertem, ale ten przykład tutaj wydaje się o wiele prostsza:

string name = (const char*) (sqlite3_column_text(res, 0)); 
Powiązane problemy