🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.std.c++
Article #1743

Re: basic_string conversions

#1743
From: Nathan Myers
Date: Sat, 19 Aug 1995 15:03
75 lines
3018 bytes
In article <MATT.95Aug17235138@physics2.berkeley.edu>,
Steve F. Cipolli <dscope!sfc@uu.psi.com> wrote:
> What is the recommended method of converting basic_string's of one 
> parameterized type to another, and from another parameterized type itself?  
> To clarify:
> 
> char *ntbs = "abc";
> wchar_t *ntcws = L"abc";
> string cs(ntbs);	// basic_string<char>(char *) - OK
> wstring ws1(ntcws);	// basic_string<wchar_t>(wchar_t *) - OK
> wstring ws2(ntbs);	// basic_string<wchar_t>(char *) - ???? 
> wstring ws3(cs);	// basic_string<wchar_t>(basic_string<char>) - ???? 
> 
> Will the last two constructors work?  If so how?
> If not, is the <cwchar> conversion function mbtowc from the C library 
> the answer?

Encodings for conversion between wide and narrow strings differ,
and you should say which encoding you mean.

Unfortunately the C functions stop when they hit a NUL character.

The correct mechanism to use is the locale facilities:

  std::wstring 
  widen(const std::string& s, const std::locale& loc = std::locale())
  {
    using namespace std;
    const char* from = s.data();
    const char* from_end = from + s.length();
    char* to = new wchar_t[s.length()];  // should be big enough.
    char* to_end = to + s.length();
    try {
      typedef codecvt<char,wchar_t,mbstate_t> Cvt;
      if (use_facet<Cvt>(loc).convert(
            from, from_end, from, 
	    to,   to_end,   to_end, mbstate_t) != codecvt_base::ok) 
	throw runtime_error();
    } catch (...) {
      delete [] to;
      throw;
    }
    wstring w(to, to_end);
    delete [] to;
    return w;
  }

Another way, somewhat less efficient but a little more robust, is:

  std::wstring 
  widen(const std::string& s, const std::locale& loc = std::locale())
  {
    using namespace std;
    wstringstream ws;
    ws.imbue(loc);
    ws << s;
    if (!ws.good()) throw runtime_error();
    return ws.str();
  }

Both of the above allow a choice of which encoding to use.

Probably the string types should provide the above conversion
in a more convenient form.

[In case anybody didn't notice, the above code is written to 
 work when Standard implementations are available.  Until then, 
 you'll need ifdefs, at least.]

Nathan Myers
myersn@roguewave.com

[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Technical Details
Message-ID: <ncmDDJ83M.Dvu@netcom.com>
Path: arc1-ca.pugleaf.net!engnews2.Eng.Sun.COM!taumet!clamage
References: <MATT.95Aug17235138@physics2.berkeley.edu>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!engnews2.Eng.Sun.COM!taumet!clamage
From: ncm@netcom.com (Nathan Myers)
Newsgroups: comp.std.c++
Subject: Re: basic_string conversions
Date: 19 Aug 1995 15:03:00 GMT
Organization: Rogue Wave Software, Inc.
Approved: clamage@eng.sun.com (comp.std.c++)
Message-ID: <ncmDDJ83M.Dvu@netcom.com>
References: <MATT.95Aug17235138@physics2.berkeley.edu>
NNTP-Posting-Host: taumet.eng.sun.com
Content-Type: text
Cc: ncm@netcom.com
Content-Length: 2234
Originator: clamage@taumet