Page 1 of 1

CEGUI::String to std::string

Posted: Fri Dec 16, 2005 11:54
by pxL
Hey,

I'm trying to conver a cegui::string to std::string and when I searched the forum I saw that std::string string( cegui::string.c_str() ) should work, but sadly it doesn't :(...

Could someone help me plz :)

Using:
Ogre CVS
Cegui 0.4.0 Stable Src
MS Visual 7.1

Code (Where it goes wrong):

Code: Select all

// Getting selected item from combobox
std::string sTest( comboRenderer->getSelectedItem()->getText().c_str() );


Callstack:
CEGUIBase_d.dll!CEGUI::String::build_utf8_buff() Line 117 + 0x3
CEGUIBase_d.dll!CEGUI::String::c_str() Line 1159
Sheathed Sword.exe!MenuState::saveOptions() Line 299 + 0x30
Sheathed Sword.exe!MenuState::bHandlerSaveOptions(const CEGUI::EventArgs & ceEvent={...}) Line 370
Sheathed Sword.exe!CEGUI::_memberBinder<MenuState,bool,CEGUI::EventArgs const &>::operator()(const CEGUI::EventArgs & args={...}) Line 102 + 0x12
CEGUIBase_d.dll!CEGUI::SubscriberTemplate<bool,CEGUI::EventArgs const &>::operator()(const CEGUI::EventArgs & args={...}) Line 120 + 0x15

Visual breaks in ceguistring.cpp @ line 117:

Code: Select all

...
utf8* String::build_utf8_buff(void) const
{
  size_type buffsize = encoded_size(ptr(), d_cplength) + 1;
...

Re: CEGUI::String to std::string

Posted: Fri Dec 16, 2005 19:50
by spannerman
Try this method:

Code: Select all

const std::string myClass::getComboBoxSelectedText(CEGUI::String comboBoxName)
{
   Combobox* cbox = (Combobox*)WindowManager::getSingleton().getWindow(comboBoxName);
   ListboxItem* listItem = cbox->getSelectedItem();
   std::string strItemText = "";

   if (listItem != NULL)
   {
      strItemText = listItem->getText().c_str();
   }

   return strItemText;
}


Pass in the name of the combo box (make sure it exists), and it will return the text of the selected listitem, if any. Notice you pass in a Cegui string, and get a std string back. Also you could maybe modify the method to pass in a referance to the combobox instead of its name.

Hope that helps

Re: CEGUI::String to std::string

Posted: Fri Dec 16, 2005 19:50
by Sponge
CEGUI::String x;
std::string z = x.c_str();

compiles for me :)

Re: CEGUI::String to std::string

Posted: Fri Dec 16, 2005 20:31
by pxL
Yea well it also compiles for me ;) but when I hit the save button it stops there :P.

Thx Spannerman I'll try it right now, but when I was reading your code I realised that I'm using this code:

Code: Select all

cmbRenderer->setText( mapVideoOptions[ "Render System" ] );

To set the setting that I get from my config file, so sometimes (if the user doesn't change renderer) there is nothing selected :oops:.

Re: CEGUI::String to std::string

Posted: Fri Dec 16, 2005 21:26
by pxL
Well it is what I suspected :D, so instead of:
comboRenderer->getSelectedItem()->getText().c_str()

I do:
comboRenderer->getText().c_str()

Which work perfectly for me :), you could also change the function that spannerman wrote by adding some code at the if-statement:

Code: Select all

const std::string myClass::getComboBoxSelectedText(CEGUI::String comboBoxName)
{
   Combobox* cbox = (Combobox*)WindowManager::getSingleton().getWindow(comboBoxName);
   ListboxItem* listItem = cbox->getSelectedItem();
   std::string strItemText = "";

   if (listItem != NULL)
   {
      strItemText = listItem->getText().c_str();
   }
   else
   {
      strItemText = cbox->getText().c_str();
   }

   return strItemText;
}


Hope this helps for future ppl who use comboBox->setText( "" ) :D

edit:
Thx for the help spannerman your code helpt me see my flaws ;)

Posted: Fri Feb 24, 2006 13:30
by Pacome
I've tested all the methods you gave, but they only works for characters without accent.

You can just try the following code which test the behaviour of String:

Code: Select all

// First, we test the CeGUI::String conversion to char*
CEGUI::String  testCEGUI = "éàùè";              // The CeGUI string contains "éàùè" in its d_quickbuff, it's OK
const char*    bufCEGUI = testCEGUI.c_str();    // The char* buffer given by CEGUI::String::c_str() contains "éà ùè" which is totally INCORRECT

// Second, we test the classical std::string conversion to char*
std::string    testSTL = "éàùè";       // The STL string contains "éàùè", it's OK
const char*    bufSTL = testSTL.c_str();    // The char* buffer given by std::string::c_str() contains "éàùè", it's OK

// Third, we test the conversion from CEGUI::String to std::string, via the c_str() method
std::string    testSTLfromCEGUI = testCEGUI.c_str();     // The STL contains the wrong string "éà ùè" instead of the initial string "éàùè".


As you see, the behaviour of CEGUI::String::c_str() and str::string::c_str() is totally different. One is correct and the other one is not.

It's a real problem for European (and other) users who use accent.
I'm french, and it's impossible for me to write without accents...

Do you have an idea to solve this problem please ?

Best regards,

Pacôme

Posted: Fri Feb 24, 2006 14:45
by jacmoe
std::string is using ascii, so you will loose the unicode-ness of the CEGUI::String.

Maybe you are better of using CEGUI::String where you can? :)

Posted: Fri Feb 24, 2006 15:06
by RenjiKage
I second jacmoe.

I made a design decision that I don't use more than one String class in my code. As I make my GUIs with CEGUI and every little bit of text the user will see is a CEGUI::String, I use it everywhere.

As for your problem, just use std::wstring. HTH.

But I also have a problem. If I define UNICODE, how can I pass a CEGUI::String to a Windows API function that doesn't accept the char* the c_str() function returns.

Posted: Sat Feb 25, 2006 13:14
by CrazyEddie
Pacome wrote:I've tested all the methods you gave, but they only works for characters without accent.

<snip>

As you see, the behaviour of CEGUI::String::c_str() and str::string::c_str() is totally different. One is correct and the other one is not.

Of course they're different, they are different classes with hugely different capabilities and internal representations :roll:

Both are "correct" according to the documentation for each function - did you bother to read the documentation for CEGUI::String::c_str at all? Does it say that it returns an ansi representation of the string data? No, it does not. It actually specifies that the buffer returned is the string encoded as UTF8 data, which is, indeed, the case.

The reason for this is because CEGUI::String can hold many more different codepoint values than the std::string can, so returning such a simple representation is impossible without the potential for data loss (what would we do with codepoint values above 255?), so after some discussion it was decided that we would return the utf8 encoded buffer instead.

In order to use the returned data to it's full potential, and access those codepoints which unencoded are >127, then you will need to decode the utf8 data. Another option is to iterate over the CEGUI::String directly and construct your own char* buffer, though wou will need to make the decision about what to do with codepoints that are >255.

Oh, and please, if in the future you have a failure to understand something, and an inability to read the API reference, do NOT visit every topic in the forum that makes mention of an involved class or member and post about your issue; you only need to post your question in it's own topic and you will get a response. This is effectively cross-posting / spamming the forums, and the abuse has been noted.

RenjiKage wrote:But I also have a problem. If I define UNICODE, how can I pass a CEGUI::String to a Windows API function that doesn't accept the char* the c_str() function returns.

The best advice I can give is similar to what I posted above. You'll need to create a helper function to iiterate over the string, and extract the codepoints and save them in a form that Windows is expecting (in this case, some form of UTF16 I believe).

HTH

CE.

Re: CEGUI::String to std::string

Posted: Mon Nov 21, 2016 11:39
by cloud
you can do the conversion in C++0x with http://en.cppreference.com/w/cpp/locale ... from_bytes

Re: CEGUI::String to std::string

Posted: Mon Nov 21, 2016 13:31
by CrazyEddie
Please do not necro ten year old threads. Thanks.

Re: CEGUI::String to std::string

Posted: Mon Nov 21, 2016 17:50
by Ident
Not only did you necro an ancient thread, you also necro'd the forum-corpse of CrazyEddie! :o

Did not read the entire thread but I would like to add something: I rewrote CEGUI::String almost entirely for C++11 and had tried to use std's string conversion functionality. It is absolutely unusable. codecvt is very poorly supported (known bugs, linker problems, etc) in Visual Studio 2013 and 2015 to the point where it makes absolutely no sense to use it.

What we have on default, and I would like to keep that, is 3 options for CEGUI::String
ASCII
UTF_8
UTF_32

Ascii type is just a typedef of std::string

UTF_8 type replicates the entire std::basic_string interface and is UTF-8 and UTF-32 aware for all inputs and has additional convenience functionality for this purpose. It can be used like an std::basic_string and internally stored a std::string, where each char is a code unit. As always, UTF-8 Is backwards compatible to ASCII. This is my personal favourite as a solution, but of course is slower than raw ASCII strings since we need to always check the code units when it comes to iteration and length checks etc.

UTF_32 stores code points and expects normalised input. We do not normalise anywhere atm., but afaik you can't keyboard-input combined characters anyways (they are received normalised already), so this would mainly be an issue for clipboards. This one is also UTF-8 aware and has convenience functions as well. Internally stores everything as std::u32string. It will of course waste a ton of memory, but computations will most likely tend be faster than in the UTF-8 version. I would still prefer the UTF-8 sring.

It is best to implement the conversions between UTF-8 and UTF-32 ourselves in our library since they are relatively simple, adding a library for it alone is quite ridiculous and we already had existing code for it which I refactored and (hopefully) improved based on what knowledge I gained from other sources and source. Codecvt would be nice but like I said it is broken and I remember there were also some caveats.

Imho, wide string and UTF-16 conversions should be done using the libraries present in your OS or wherever - clearly those libraries are using UTF-16 if they give it to you, so this duty is something we leave to the Windows, etc. functions. Since both UTF_32 and UTF_8 are supported in the unicode CEGUI::String types, there should be no issue to get at least one unicode type we support.

Edit:
Added a ticket to remind me of the normalisation stuff, we should do this for 1.0 if possible: https://bitbucket.org/cegui/cegui/issue ... ter-inputs