1,105,625 Community Members

How to convert wchar_t* to char*?

Member Avatar
jaepi
Practically a Master Poster
647 posts since Jul 2006
Reputation Points: 22 [?]
Q&As Helped to Solve: 6 [?]
Skill Endorsements: 0 [?]
 
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*?

Member Avatar
Ancient Dragon
Achieved Level 70
27,632 posts since Aug 2005
Reputation Points: 5,232 [?]
Q&As Helped to Solve: 3,037 [?]
Skill Endorsements: 115 [?]
Team Colleague
Featured
Sponsor
 
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.

Member Avatar
jaepi
Practically a Master Poster
647 posts since Jul 2006
Reputation Points: 22 [?]
Q&As Helped to Solve: 6 [?]
Skill Endorsements: 0 [?]
 
0
 

thank you sir, i'll try it.

Member Avatar
vijayan121
Posting Virtuoso
1,769 posts since Dec 2006
Reputation Points: 1,097 [?]
Q&As Helped to Solve: 329 [?]
Skill Endorsements: 16 [?]
 
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' ;
  } 
}
Member Avatar
jaepi
Practically a Master Poster
647 posts since Jul 2006
Reputation Points: 22 [?]
Q&As Helped to Solve: 6 [?]
Skill Endorsements: 0 [?]
 
0
 

Thanks!

Member Avatar
utruppo
Newbie Poster
1 post since Jan 2011
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
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;
}
Member Avatar
epolgar
Newbie Poster
2 posts since Oct 2011
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
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
Member Avatar
epolgar
Newbie Poster
2 posts since Oct 2011
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
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 three months: Start a new discussion instead
Post:
Start New Discussion
Tags Related to this Article