Reputation: 1655
sqlite3_column_text returns a const unsigned char*, how do I convert this to a std::string? I've tried std::string(), but I get an error.
Code:
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
Upvotes: 59
Views: 80460
Reputation: 500
An old but important question, if you have to preserve the full information in the unsigned char sequence. In my opinion that is with reinterpret_cast not the case. I found an interesting solution under converting string to vector which I modified to
basic_string<unsigned char> temp = sqlite3_column_text(stmt, 0);
string firstItem( temp.begin(), temp.end() );
Since I am programming for gtkmm, you can realize the conversion into a Glib::ustring with
basic_string<unsigned char> temp = sqlite3_column_text(stmt, 0);
Glib::ustring firstItem = string( temp.begin(), temp.end() );
Upvotes: 1
Reputation: 46
I'm no expert but this example here seems much simpler:
string name = (const char*) (sqlite3_column_text(res, 0));
Upvotes: 2
Reputation: 2182
The reason people typically use an (unsigned char *) type is to indicate that the data is binary and not plain ASCII text. I know libxml does this, and from the looks of it, sqlite is doing the same thing.
The data you're getting back from the sqlite call is probably UTF-8 encoded Unicode text. While a reinterpret_cast may appear to work, if someone ever stores text in the field that is not plain ASCII, your program probably won't be well-behaved.
The std::string class isn't designed with Unicode in mind, so if you ask for the length() of a string, you'll get the number of bytes, which, in UTF-8, is not necessarily the same thing as the number of characters.
Short answer: the simple cast may work, if you're certain the data is just ASCII. If it can be any UTF-8 data, then you need to handle encoding/decoding in a smarter way.
Upvotes: 21
Reputation:
On the off-chance you actually want a string of unsigned characters, you could create your own type:
typedef std::basic_string <unsigned char> ustring;
You should then be able to say things like:
ustring s = sqlite3_column_text(this->stmts.read_documents, 0);
Upvotes: 21
Reputation: 4159
You can't construct a std::string
from const unsigned char*
-- you have to cast it to const char*
first:
temp_doc.uuid = std::string( reinterpret_cast< const char* >(
sqlite3_column_text(this->stmts.read_documents, 0) ) );
Upvotes: 2
Reputation: 12150
try:
temp_doc.uuid = std::string(reinterpret_cast<const char*>(sqlite3_column_text(this->stmts.read_documents, 0)));
Upvotes: 3
Reputation: 8031
You could try:
temp_doc.uuid = std::string(reinterpret_cast<const char*>(
sqlite3_column_text(this->stmts.read_documents, 0)
));
While std::string
could have a constructor that takes const unsigned char*
, apparently it does not.
Why not, then? You could have a look at this somewhat related question: Why do C++ streams use char instead of unsigned char?
Upvotes: 77
Reputation: 5114
if temp_doc.uuid is a std::string try :
temp_doc.uuid = static_cast<const char*>(sqlite3_column_text(this->stmts.read_documents, 0));
Upvotes: 3
Reputation: 5384
I'm not familiar with sqlite3_column_text, but one thing you may want to do is when you call the std:string constructor, you'll want to cast to (const char*). I believe that it should have a constructor for that type.
However, it is odd that this sqlite function is return an unsigned char*, is it returning a Pascal string (first char is the length of the string)? If so, then you'll have to create the std::string with the bytes and the length.
Upvotes: 4