1.11M Members

How to convert wchar_t* to char*?

 
0
 

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*?

 
0
 

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.

 
0
 

thank you sir, i'll try it.

 
2
 

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' ;
  } 
}
 
0
 

Thanks!

 
0
 

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;
}
 
0
 

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
 
0
 

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' ;
  } 
}
You
This article has been dead for over six months: Start a new discussion instead
Post:
Start New Discussion
Tags Related to this Article