• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
michaelmk86

Convert std::string to WCHAR ?

21 posts in this topic

I am trying to do this:

std::string s;

WCHAR w = s;

Also what do you mean what platform i am using?

-1

Share this post


Link to post
Share on other sites
std::string multi("Test");
std::wstring unicode(multi.begin(), multi.end());

This is the easiest form of multibyte to unicode conversion I know, won't even throw a compiler warning, unlike some solutions like std::copy. Then you can access the single characters of the wstring to get your WCHAR. Though given the little information and SiCranes answer which makes me a bit unsure, so please don't hit me if I misunderstood the actual problem ;)

 

EDIT:

 

Well given your next post it seems like it, but you can't simple do WCHAR = wstring eigther, as you can't do char = string. You rather want to do something amongst those lines, right?

 

std::wstring unicode; // suppose you used the method mentioned above to convert from string towstring
WCHAR w[256] = unicode.c_str() // you can only assign a (w)string to a (w)char array, not a single (w)char
Edited by Juliean
2

Share this post


Link to post
Share on other sites

I don't understand, the above code it giving me an error.

 

basically what i want is something like this

WCHAR convert(std::string s)
{
	WCHAR w;
	//do whatever needs to be done
	return w;
}


std::string s = "something";
WCHAR  w = convert(s);
0

Share this post


Link to post
Share on other sites

A string is a sequence of zero or potentially many characters. A WCHAR is exactly one character. You cannot just cram a string into a single character.

 

What is the actual problem you're trying to solve?

0

Share this post


Link to post
Share on other sites

A string is a sequence of zero or potentially many characters. A WCHAR is exactly one character. You cannot just cram a string into a single character.

 

What is the actual problem you're trying to solve?

to pass a string  in the second parameter here 

WCHAR* filename = L"file path...";

D3DX11CreateShaderResourceViewFromFile(device, filename, NULL, NULL, &texture, NULL);
0

Share this post


Link to post
Share on other sites

This snippet always worked for me:

 

  std::wstring      ToStringW( const std::string& strText )
  {
    std::wstring      wstrResult;
    wstrResult.resize( strText.length() );
    typedef std::codecvt<wchar_t, char, mbstate_t> widecvt;
    std::locale     locGlob;
    std::locale::global( locGlob );
    const widecvt& cvt( std::use_facet<widecvt>( locGlob ) );
    mbstate_t   State;
    const char*       cTemp;
    wchar_t*    wTemp;
    cvt.in( State,
            &strText[0], &strText[0] + strText.length(), cTemp,
            (wchar_t*)&wstrResult[0], &wstrResult[0] + wstrResult.length(), wTemp );
               
    return wstrResult;
  }

 

Then use .c_str() on the std::wstring to get a WCHAR* like.

0

Share this post


Link to post
Share on other sites

Here is one nice small snippet. 

const wchar_t* to_wide( const std::string& strToConvert ) {
  return std::wstring( strToConvert.begin(), strToConvert.end() ).c_str();
}
 

 

Notice: not working, skip it. I just leave it as is, to be here as warning how NOT to do some things.

Edited by streamer
-2

Share this post


Link to post
Share on other sites

This code is deeply broken. You're returning a pointer to memory that is freed when the function exits (because the temporary wstring will be destructed). It may seem to work, but that's the horrifying reality of undefined behavior - it often seems to work until it bites you viciously.

 

+1 for noticing this, I totally read over it to be honestly. Especially noteworth that this can, and will lead to many horrible things happening - for example, in my first resource cache class, I was storing the resources by LPCWSTR. It seemed to work fine while I was only hardcoding everything in the code, but after a while I got an issue where setting constant to my effects was only working sporadically. Turned out the LPCWSTR-keys got trashed, and whenever accessing an effect from the cache, a new isntance was loaded and stored in another key that became trashed, and so forward. Wouldn't even had thought about looking there in the first place, as it appeared to be a graphics-related error. Moral of the story: Always double-check on how you use your strings.

0

Share this post


Link to post
Share on other sites

Here is my implementation:

 

		template <typename T>
			size_t SizeOfStr(T * str)
			{
				if(!str) return 0 ;
				size_t i = 0 ;
				while(str[i++]);
				return i ;
			}

		template <typename T , typename U >
			U * ConvertStr(T * t, size_t Size = 0)
			{
				if(!Size)
				{
					Size = SizeOfStr(t);
				}

				U * u = new U[Size]; 
				for(size_t i = 0 ; i < Size ; i++ ) u[i] = U(t[i]);
				return u ;
			}

 

Do not forget to clean resources once you are done.. smile.png

Edited by Eliad Moshe
0

Share this post


Link to post
Share on other sites

I solve my problem by doing the following:

 

std::wstring s2ws(const std::string& s)
{
	int len;
	int slength = (int)s.length() + 1;
	len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
	wchar_t* buf = new wchar_t[len];
	MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
	std::wstring r(buf);
	delete[] buf;
	return r;
}

#ifdef UNICODE
std::wstring stemp = s2ws(filename); // Temporary buffer is required
LPCTSTR L_filename = stemp.c_str();
#else
LPCTSTR L_filename = s.c_str();
#endif
	
D3DX11CreateShaderResourceViewFromFile(device, L_filename, NULL, NULL, &texture, NULL);

i just couldn't imagine such a simple thing to be that complicated.


 

0

Share this post


Link to post
Share on other sites

i just couldn't imagine such a simple thing to be that complicated.

 

And you didn't do it as simple as:

 

std::wstring s2ws(const std::string& s)
{   
	return std::wstring(s.begin(), s.end());
}

#ifdef UNICODE
std::wstring stemp = s2ws(filename); // Temporary buffer is required
#else
std::Wstring stemp = s;
#endif
	
D3DX11CreateShaderResourceViewFromFile(device, stemp.c_str(), NULL, NULL, &texture, NULL);

 

like suggested because of... ?

Edited by Juliean
2

Share this post


Link to post
Share on other sites
behold the magic trick 1:

D3DX11CreateShaderResourceViewFromFileA(device, filename.c_str(), NULL, NULL, &texture, NULL);


Notice the final A? That will give you the (char*) version of the function as opposed to the WCHAR* version of it.

If you really want to use the WCHAR* .. the code is quite easy:

wstring l_filename(filename.begin(),filename.end());
D3DX11CreateShaderResourceViewFromFile(device, l_filename.c_str(), NULL, NULL, &texture, NULL); Edited by kunos
1

Share this post


Link to post
Share on other sites

Here is one nice small snippet.

const wchar_t* to_wide( const std::string& strToConvert ) {
  return std::wstring( strToConvert.begin(), strToConvert.end() ).c_str();
}
 

 

This code is deeply broken. You're returning a pointer to memory that is freed when the function exits (because the temporary wstring will be destructed). It may seem to work, but that's the horrifying reality of undefined behavior - it often seems to work until it bites you viciously.

 

You are right! :)

 

+1 for noticing it.

0

Share this post


Link to post
Share on other sites

My C++ is a bit rusty ... but perhaps 

std::wstring toWideString(std::string & str) {
  std::wstringstream ws;
  ws << str.c_str();
  return ws.str();
} 
0

Share this post


Link to post
Share on other sites

My C++ is a bit rusty ... but perhaps

std::wstring toWideString(std::string & str) {
std::wstringstream ws;
ws << str.c_str();
return ws.str();
}

 

Should work, but is still more complicated than the wstring-ctor solution offered above many times.

1

Share this post


Link to post
Share on other sites

Here is my implementation:

 

		template <typename T>
			size_t SizeOfStr(T * str)
			{
				if(!str) return 0 ;
				size_t i = 0 ;
				while(str[i++]);
				return i ;
			}

		template <typename T , typename U >
			U * ConvertStr(T * t, size_t Size = 0)
			{
				if(!Size)
				{
					Size = SizeOfStr(t);
				}

				U * u = new U[Size]; 
				for(size_t i = 0 ; i < Size ; i++ ) u[i] = U(t[i]);
				return u ;
			}

 

Do not forget to clean resources once you are done.. smile.png

Converting character code points doesn't work like that (at least for any code points requiring multiple bytes). If the input string is UTF-8 (and has any code points requiring more than one byte), that will not convert it right (For example, 0xC482 (UTF-8 "?") will be converted to 0x00C40082, which is not the right conversion).

0

Share this post


Link to post
Share on other sites

If the input string is ASCII, you can easily expand the string using the methods given above. However if the input string is unicode, that won't work. In unicode a single character can consist of multiple code points which in turn can consist of multiple bytes. Typically you don't think in characters when encoding strings, but in code points. This is because unicode can combine characters from two code points, for example ' and e become é (although in this particular case there is a code point for é as well). This is also why you can never compare if two unicode strings are equal without normalizing them first. Unicode also has over a million code points (although not all are used yet), but a byte can only hold 256 and a 16-bit wchar only 65536. In order to be able to store all million code points, both UTF-8 and UTF-16 (although lots of people seem to forget this about the latter) encode code points in one or more pairs. For UTF-8 this means a single code point can take 1, 2, 3 or 4 bytes, for UTF-16 it's always 2 or 4. That means when converting, you first have to decode the code point, then encode it again, there is no direct convertion byte by byte possible.

 

You could do this yourself, it's not that hard and a good exercise to make a UTF-8 to UTF-16 converter. I would be useful if you start mixing the two to actually understand how it works, rather then to copy/paste a piece of code that may or may not work, or code that will later fail (the wstring constructor trick seems to fail horribly if your string is non-ascii). Or lookup boost, it has some conversion stuff in it as well.

1

Share this post


Link to post
Share on other sites

If the input string is ASCII, you can easily expand the string using the methods given above. However if the input string is unicode, that won't work.

 

Principally, it does:

 

std::wstring wide(L"does not contain special UTF letters");
std::string multi(wide.begin(), wide.end();
std::cout << multi.c_str();

I used this to convert a wstring for output with a filestream. Though I didn't try it out with "special" UTF-chars, it surely won't work with them, would be interesting whats the result though...

0

Share this post


Link to post
Share on other sites

To be honest, with the codebase I work on in MSVS, I just use _bstr_t to convert, which has constructors taking either type, and operators returning either type.

It turns this into a trivial one-liner. E.g.

 

std::wstring toWString(const std::string &as) { return _bstr_t(as); }
std::string toAString(const std::wstring &ws) { return _bstr_t(ws); }

http://msdn.microsoft.com/en-us/library/btdzb8eb(v=vs.71).aspx

http://msdn.microsoft.com/en-us/library/9k3ebasf(v=vs.71).aspx

Edited by iMalc
0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0