Start New Discussion within our Software Development Community

Hello there, I have here a problem with the function open(). Since its first parameter asks for a char*, how would i convert wchar_t* to char* if my program asks for a wchar_t* as its path rather than char*?

I like to use wcstombs() because it is pretty easy to use. There are, however, other more powerful fuctions that may be better used for some languages such as Chinese.

an alternative is to use the ctype<> facet. the advantages are a. also works with c++ strings b. locales other than the default locale are supported (behaviour is unaffected by the LC_CTYPE category of the current c locale). 3. will not fail if a wide-character code encountered does not correspond to a valid character.

#include <locale>
#include <iostream>
#include <string>
#include <sstream>
using namespace std ;

wstring widen( const string& str )
{
    wostringstream wstm ;
    const ctype<wchar_t>& ctfacet = 
                        use_facet< ctype<wchar_t> >( wstm.getloc() ) ;
    for( size_t i=0 ; i<str.size() ; ++i ) 
              wstm << ctfacet.widen( str[i] ) ;
    return wstm.str() ;
}

string narrow( const wstring& str )
{
    ostringstream stm ;
    const ctype<char>& ctfacet = 
                         use_facet< ctype<char> >( stm.getloc() ) ;
    for( size_t i=0 ; i<str.size() ; ++i ) 
                  stm << ctfacet.narrow( str[i], 0 ) ;
    return stm.str() ;
}

int main()
{
  {
    const char* cstr = "abcdefghijkl" ;
    const wchar_t* wcstr = widen(cstr).c_str() ;
    wcout << wcstr << L'\n' ;
  }
  {  
    const wchar_t* wcstr = L"mnopqrstuvwx" ;
    const char* cstr = narrow(wcstr).c_str() ;
    cout << cstr << '\n' ;
  } 
}
Comments
I didn't know this. Thank you.

Working wersion, witch proper memory allocation

char* narrow( const wstring& str )
{
	ostringstream stm ;
	const ctype<char>& ctfacet =
	use_facet< ctype<char> >( stm.getloc() ) ;
	for( size_t i=0 ; i<str.size() ; ++i )
		stm << ctfacet.narrow( str[i], 0 ) ;
	string str = stm.str();
	char* c = new char [str.size()+1];
	strcpy(c, str.c_str());
	return c;
}


int main()
{
	const wchar_t* wcstr = L"mnopqrstuvwx";
	const char* cstr = narrow(wcstr);
	cout << cstr << '\n' ;
	delete message;
}

I would just include a couple of changes to the first program solution by vijavan121.. I would suggest (besides adding a stdafx.h file to the project and there, to include the actual declaration of the functions' signatures [in the stdafx.h] and obviously the include headers)... you actually need to pass in a reference to your wstring to the widen function and a string reference to the second one, so that your code actually works...and so it would look something like this...

// TestTemplatesWChar2.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
using namespace std;

wstring* widen( const string& str, wstring& incomingString)
{    
	wostringstream wstm; 
	const ctype<wchar_t>& ctfacet =                         
			use_facet< ctype<wchar_t> >( wstm.getloc() );    
	
	for( size_t i=0; i<str.size(); ++i )
		wstm << ctfacet.widen( str[i] );    
	
	wstm << L"\n";

	incomingString =  wstm.str();
	return &incomingString;
} 

string* narrow( const wstring& str, string& incomingString )
{
	ostringstream stm;    
	const ctype<char>& ctfacet =                          
		use_facet< ctype<char> >( stm.getloc() );    
	
	for( size_t i=0; i<str.size(); ++i )                   
		stm << ctfacet.narrow( str[i], 0 );
	
	stm << "\n";
	incomingString = stm.str();

	return &incomingString;
}

int _tmain(int argc, _TCHAR* argv[])
{
    wstring mylongerstring;
	const char* cstr = "abcdefghijkl";
	wstring* wstringPointer = widen(cstr, mylongerstring);
	const wchar_t* wcstr = (*wstringPointer).c_str();    
	wcout << wcstr << L'\n';  

	string myshorterstring;
	wcstr = L"mnopqrstuvwx";
	string* stringPointer = narrow(wcstr, myshorterstring);
	cstr = (*stringPointer).c_str();    
	cout << cstr << '\n';  

	return 0;
}

good luck with that... if you need the stdafx.h, here it is...

// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//

#pragma once

#ifndef _WIN32_WINNT		// Allow use of features specific to Windows XP or later.                   
#define _WIN32_WINNT 0x0501	// Change this to the appropriate value to target other versions of Windows.
#endif						

#include <stdio.h>
#include <tchar.h>
#include <locale>
#include <iostream>
#include <string>
#include <sstream>

using namespace std;

wstring* widen( const string& str);
string* narrow( const wstring& str );
// TODO: reference additional headers your program requires here

IN RESPONSE TO YOUR ANSWER TO A MESSAGE POSTED .... Look at your qoute :


You needed a little bit of tweaking for your code to work... I put a comment at the end of the thread (at the end today, 10/17/11) and here is a little bit more with some error checking...

I had commented that you need to pass to variables references to your functions so that the code you wrote would actually work and in case you were wondering why I return pointers to the actual string and wstring, it is for simple error checking before using them, like this....

// TestTemplatesWChar2.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <assert.h>

using namespace std;

wstring* widen( const string& str, wstring& incomingString)
{    
	wostringstream wstm; 
	const ctype<wchar_t>& ctfacet =                         
			use_facet< ctype<wchar_t> >( wstm.getloc() );    
	
	for( size_t i=0; i<str.size(); ++i )
		wstm << ctfacet.widen( str[i] );    
	
	wstm << L"\n";

	incomingString =  wstm.str();
	return &incomingString;
} 

string* narrow( const wstring& str, string& incomingString )
{
	ostringstream stm;    
	const ctype<char>& ctfacet =                          
		use_facet< ctype<char> >( stm.getloc() );    
	
	for( size_t i=0; i<str.size(); ++i )                   
		stm << ctfacet.narrow( str[i], 0 );
	
	stm << "\n";
	incomingString = stm.str();

	return &incomingString;
}

int _tmain(int argc, _TCHAR* argv[])
{
    wstring mylongerstring;
	const char* cstr = "abcdefghijkl";
	wstring* wstringPointer = widen(cstr, mylongerstring);
	const wchar_t* wcstr;

	assert(wstringPointer);

	if(wstringPointer != NULL)
	{
		wcstr = (*wstringPointer).c_str();    
		wcout << wcstr << L'\n';
	}

	string myshorterstring;
	wcstr = L"mnopqrstuvwx";
	string* stringPointer = narrow(wcstr, myshorterstring);
	
	assert(stringPointer);

	if(stringPointer != NULL)
	{
		cstr = (*stringPointer).c_str();    
		cout << cstr << '\n';  
	}

	return 0;
}

an alternative is to use the ctype<> facet. the advantages are a. also works with c++ strings b. locales other than the default locale are supported (behaviour is unaffected by the LC_CTYPE category of the current c locale). 3. will not fail if a wide-character code encountered does not correspond to a valid character.

#include <locale>
#include <iostream>
#include <string>
#include <sstream>
using namespace std ;

wstring widen( const string& str )
{
    wostringstream wstm ;
    const ctype<wchar_t>& ctfacet = 
                        use_facet< ctype<wchar_t> >( wstm.getloc() ) ;
    for( size_t i=0 ; i<str.size() ; ++i ) 
              wstm << ctfacet.widen( str[i] ) ;
    return wstm.str() ;
}

string narrow( const wstring& str )
{
    ostringstream stm ;
    const ctype<char>& ctfacet = 
                         use_facet< ctype<char> >( stm.getloc() ) ;
    for( size_t i=0 ; i<str.size() ; ++i ) 
                  stm << ctfacet.narrow( str[i], 0 ) ;
    return stm.str() ;
}

int main()
{
  {
    const char* cstr = "abcdefghijkl" ;
    const wchar_t* wcstr = widen(cstr).c_str() ;
    wcout << wcstr << L'\n' ;
  }
  {  
    const wchar_t* wcstr = L"mnopqrstuvwx" ;
    const char* cstr = narrow(wcstr).c_str() ;
    cout << cstr << '\n' ;
  } 
}
This article has been dead for over six months. Start a new discussion instead.