tags:

views:

3657

answers:

7

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
+9  A: 

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?

Pukku
+1. although, I think you should make that "const char *" inside your angle brackets. You don't want to be trying to cast away the const-ness (which it may not even allow).
rmeador
Very true! Thanks for the remark.
Pukku
I get this error:1>.\storage_manager.cpp(109) : error C2440: 'static_cast' : cannot convert from 'const unsigned char *' to 'const char *'1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
LM
Uh-oh. Well, maybe you need reinterpret_cast instead of static_cast, then?
Pukku
Since I'm quite sure that it will work, I'll edit the answer too.
Pukku
Thanks! It worked - but why do you need to do it that way?
LM
You mean reinterpret_cast instead of static_cast? See: http://stackoverflow.com/questions/573294/when-to-use-reinterpretcast
Pukku
+3  A: 

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.

Lyndsey Ferguson
+1  A: 

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) ) );
Kasprzol
So - there's no way at all?
LM
sorry, have to use reinterpret_cast instead of static_cast.
Kasprzol
+1  A: 

if temp_doc.uuid is a std::string try :

temp_doc.uuid = static_cast<const char*>(sqlite3_column_text(this->stmts.read_documents, 0));
Raoul Supercopter
It is a std::string, and trying out your method gives me:1>.\storage_manager.cpp(109) : error C2440: 'static_cast' : cannot convert from 'const unsigned char *' to 'const char *'1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
LM
+2  A: 

try:

temp_doc.uuid = std::string(reinterpret_cast<const char*>(sqlite3_column_text(this->stmts.read_documents, 0)));
I saw someone already posted the answer , I started to write this answer before the other was posted(was checking that the answer is correct in VS)
Thanks! It worked - but why do you need to do it that way?
LM
I am only saying it so I won't think I copy answers
I am only saying it so you won't think I copy answers
const char* and const unsigned char* are not the same type. string constructor expect const char* and therefor a cast is needed
+5  A: 

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);
anon
+1 I think this would have been the best option.
GMan
+2  A: 

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.

Mike Mueller
Is there a way of doing this with the std:: library?
LM
Not that I know of. The standard approach is to use a 3rd party library, for example: http://site.icu-project.org/
Mike Mueller