CEGUI::String to std::string

For help with anything that CEGUI doesn't offer straight out-of-the-box, e.g.:
- Implementation of new features, such as new Core classes, widgets, WindowRenderers, etc. ...
- Modification of any existing features for specific purposes
- Integration of CEGUI in new engines or frameworks and writing of new plugins (Renderer, Parser, ...) or modules

Moderators: CEGUI MVP, CEGUI Team

User avatar
pxL
Just popping in
Just popping in
Posts: 14
Joined: Mon Oct 31, 2005 16:05

CEGUI::String to std::string

Postby pxL » Fri Dec 16, 2005 11:54

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;
...

User avatar
spannerman
Home away from home
Home away from home
Posts: 330
Joined: Wed Jan 12, 2005 12:06

Re: CEGUI::String to std::string

Postby spannerman » Fri Dec 16, 2005 19:50

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

User avatar
Sponge
Just popping in
Just popping in
Posts: 16
Joined: Tue Nov 08, 2005 18:17
Location: Fryslan, The Netherlands
Contact:

Re: CEGUI::String to std::string

Postby Sponge » Fri Dec 16, 2005 19:50

CEGUI::String x;
std::string z = x.c_str();

compiles for me :)

User avatar
pxL
Just popping in
Just popping in
Posts: 14
Joined: Mon Oct 31, 2005 16:05

Re: CEGUI::String to std::string

Postby pxL » Fri Dec 16, 2005 20:31

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:.

User avatar
pxL
Just popping in
Just popping in
Posts: 14
Joined: Mon Oct 31, 2005 16:05

Re: CEGUI::String to std::string

Postby pxL » Fri Dec 16, 2005 21:26

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 ;)

User avatar
Pacome
Just popping in
Just popping in
Posts: 14
Joined: Fri Dec 02, 2005 11:54
Contact:

Postby Pacome » Fri Feb 24, 2006 13:30

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

User avatar
jacmoe
Just can't stay away
Just can't stay away
Posts: 136
Joined: Sun Apr 03, 2005 14:18
Location: Holbaek, Denmark
Contact:

Postby jacmoe » Fri Feb 24, 2006 14:45

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? :)

User avatar
RenjiKage
Just popping in
Just popping in
Posts: 10
Joined: Sat Nov 26, 2005 15:56
Location: Kokubunji-shi, Tokyo-to, Japan

Postby RenjiKage » Fri Feb 24, 2006 15:06

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.

User avatar
CrazyEddie
CEGUI Project Lead
Posts: 6760
Joined: Wed Jan 12, 2005 12:06
Location: England
Contact:

Postby CrazyEddie » Sat Feb 25, 2006 13:14

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.

cloud
Just popping in
Just popping in
Posts: 2
Joined: Fri Sep 24, 2010 09:05

Re: CEGUI::String to std::string

Postby cloud » Mon Nov 21, 2016 11:39

you can do the conversion in C++0x with http://en.cppreference.com/w/cpp/locale ... from_bytes

User avatar
CrazyEddie
CEGUI Project Lead
Posts: 6760
Joined: Wed Jan 12, 2005 12:06
Location: England
Contact:

Re: CEGUI::String to std::string

Postby CrazyEddie » Mon Nov 21, 2016 13:31

Please do not necro ten year old threads. Thanks.

User avatar
Ident
CEGUI Team
Posts: 1998
Joined: Sat Oct 31, 2009 13:57
Location: Austria

Re: CEGUI::String to std::string

Postby Ident » Mon Nov 21, 2016 17:50

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
CrazyEddie: "I don't like GUIs"


Return to “Modifications / Integrations / Customisations”

Who is online

Users browsing this forum: No registered users and 6 guests