Topic: STL's wstring and string
Author: sirwillard@my-deja.com
Date: 1999/11/16 Raw View
In article <382559b7.16317994@news.netvision.net.il>,
yariv@eldat.com (Yariv Saar) wrote:
>
> Hi,
> I need do convert a wide-string variable into a char pointer, to be
> able to pass it as a parameter in GetPrivateProfileInt (for instance).
>
> What's the standard (STL) way of doing such a conversion?
The standard way, or the STL way? This is *precisely* why I hate using
the acronym STL when describing a part of the standard library. The
true STL doesn't even define a string class. The portion of the
standard that is based on the STL does define a string class, but
provides little useful mechanisms for what you want to do (codecvt is
supposed to handle this very circumstance, but it's use is complicated
enough to render it useless in the face of the "true answer").
However, the standard DOES provide a mechanism to do the conversion
outside of the "STL" portion... mbstowcs and wcstombs.
It's probably worth while to wrap these standard C functions in an
object. Don Box defines a "shim" class that does this in his yacl (yet
another com library) library. A quick web search will locate the code
for you. He does have a minor "bug" in the code where some strings may
have problems with the buffer size he allocates, but the fix is simple
(call mbstowcs or wcstombs with a NULL first parameter to retrieve the
size needed). If you want, I can e-mail you code I have for a similar
shim class with the bug fix (and minus the ustr functions, which are
pretty much not needed with string and wstring).
Sent via Deja.com http://www.deja.com/
Before you buy.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Joe O'Leary" <jmoleary@earthlink.net>
Date: 1999/11/09 Raw View
You might want to take a look at the std::codecvt<> template. It has member
functions (do_widen, do_narrow, etc) which appear to fit the bill.
Joe O'
Yariv Saar <yariv@eldat.com> wrote in message
news:382559b7.16317994@news.netvision.net.il...
>
> Hi,
> I need do convert a wide-string variable into a char pointer, to be
> able to pass it as a parameter in GetPrivateProfileInt (for instance).
>
> What's the standard (STL) way of doing such a conversion?
> Thanks in advance,
>
> Yariv
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Darin Adler <darin@bentspoon.com>
Date: 1999/11/09 Raw View
Joe O'Leary <jmoleary@earthlink.net> wrote:
> You might want to take a look at the std::codecvt<> template. It has member
> functions (do_widen, do_narrow, etc) which appear to fit the bill.
I considered mentioning this in my message and intentionally omitted it.
As far as I can tell, the codecvt functions convert a single character in
one encoding to a single character in another encoding. They can't possibly
help convert characters from the 16-bit encoding that don't fit within a
single character in the 8-bit encoding.
On the other hand, if you want to convert only characters that exist in both
encodings, you might find them useful, but I think that their interfaces
don't lend themselves to straightforward use with string and wstring.
-- Darin
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Dietmar Kuehl <dietmar.kuehl@claas-solutions.de>
Date: 1999/11/11 Raw View
Hi,
In article <B44DB02F.8335%darin@bentspoon.com>,
Darin Adler <darin@bentspoon.com> wrote:
> Joe O'Leary <jmoleary@earthlink.net> wrote:
> > You might want to take a look at the std::codecvt<> template. It
has member
> > functions (do_widen, do_narrow, etc) which appear to fit the bill.
Actually, 'std::codecvt' does not have these members, these are members
of 'std::ctype'. These members are also the protected, virtual versions
which cannot be called by a user directly. The corresponding public
functions are called 'widen()' and 'narrow()'. In addition to any
preprocessing, these functions call the corresponding virtual functions.
This separation of call and override interface is used throughout the
while locales library.
> As far as I can tell, the codecvt functions convert a single character
in
> one encoding to a single character in another encoding. They can't
possibly
> help convert characters from the 16-bit encoding that don't fit within
a
> single character in the 8-bit encoding.
Nope, this is not true. It is, however, true for the mentioned functions
but these are members of 'std::ctype' anyway. The functions 'in()' and
'out()' (plus their supporting functions like eg. 'unshift()') from
'std::codecvt' can be used to convert between arbitrary character
encodings. In particular, they can be used to convert a wide character
into a multi character sequence. These functions are used, if necessary,
to do necessary conversions in 'std::basic_filebuf'.
The 'std::codecvt' is suposed to convert between an external and an
internal character representation. The internal character representation
is a fixed width representation and the type used for the internal
representation is given as first template argument to 'codecvt'. The
external character representation can be basically some arbitrary
representation. This includes representations with fixed width, varying
width, and shift states. The type used to represent the external
character representation is given as second template argument. Typically
this is just 'char' such that a sequence of internal characters is
represented by a sequence of 'char's which can be used with typical
system calls. To maintain shift states and buffers, an object is used
to store the current state (eg. shift states, partial characters, etc.).
The type of this object is given as third template argument, normally
'std::mbstate_t' is used.
> On the other hand, if you want to convert only characters that exist
in both
> encodings, you might find them useful, but I think that their
interfaces
> don't lend themselves to straightforward use with string and wstring.
The interface of 'narrow()' and 'widen()' is quite straightforward,
however the interface of 'in()' and 'out()' is, indeed, not. The major
use of 'std::codecvt' is probably in 'std::basic_filebuf' and maybe a
stream buffer doing a similar conversion (if I got my implementation of
'std::basic_filebuf' done, I want to submit a corresponding stream
buffer to <http://www.boost.org/>). I doubt that many users will ever
use the 'std::codecvt' facet directly... Whether the use of 'std::ctype'
or 'std::codecvt' is appropriate for the problem of the original is not
at all clear to me: I don't really know what he wants to do.
--
<mailto:dietmar.kuehl@claas-solutions.de>
homepage: <http://www.informatik.uni-konstanz.de/~kuehl>
Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Warren Seltzer" <a-wseltz@microsoft.com>
Date: 1999/11/11 Raw View
I don't think you don't need to convert it to a char pointer. If the
program is going to run on
NT or Win2k just use VC6 and both the -A and -W versions of
GetPrivateProfileInt
are defined. You should be able to explicitly call GetPrivateProfileIntW,
if ALL your
args are wide strings. You could also define UNICODE...
I wasn't able to find an automatic conversion in the STL, but the replies
involving transform
might be right. I just wrote a routine using wcstombs and made sure I had
the memory
space it required.
Yariv Saar <yariv@eldat.com> wrote in message
news:382559b7.16317994@news.netvision.net.il...
> Hi,
> I need do convert a wide-string variable into a char pointer, to be
> able to pass it as a parameter in GetPrivateProfileInt (for instance).
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Hyman Rosen <hymie@prolifics.com>
Date: 1999/11/11 Raw View
Christopher Eltschka <celtschk@physik.tu-muenchen.de> writes:
> char* destination = new char[size+1];
> delete destination;
It's altogether too easy to make this mistake...
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: yariv@eldat.com (Yariv Saar)
Date: 1999/11/07 Raw View
Hi,
I need do convert a wide-string variable into a char pointer, to be
able to pass it as a parameter in GetPrivateProfileInt (for instance).
What's the standard (STL) way of doing such a conversion?
Thanks in advance,
Yariv
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Darin Adler <darin@bentspoon.com>
Date: 1999/11/08 Raw View
Yariv Saar <yariv@eldat.com> wrote:
> I need do convert a wide-string variable into a char pointer, to be
> able to pass it as a parameter in GetPrivateProfileInt (for instance).
>
> What's the standard (STL) way of doing such a conversion?
You can convert it to a "const wchar_t*" with c_str() or data().
If you want to convert a wide string into a narrow string, you'll need to
convert the 16-bit character encoding to some kind of 8-bit encoding. There
is some standard stuff in <locale> to convert from one character encoding to
another, but I'm not sure it would help you.
-- Darin
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Valentin Bonnard <Bonnard.V@wanadoo.fr>
Date: 1999/11/08 Raw View
Yariv Saar wrote:
> I need do convert a wide-string variable into a char pointer, to be
> able to pass it as a parameter in GetPrivateProfileInt (for instance).
Long answer:
A wide-string contains *wide* caracters (obviously).
How to pass wide-caracters depends on the specification of
GetPrivateProfileInt. If GetPrivateProfileInt takes
``const wchar_t* null_ternimated'' as parameter, then use
wstring::c_str (). If GetPrivateProfileInt takes ``const char*
null_ternimated'' then read the doc to know if GetPrivateProfileInt
can handle wide caracters and if so how.
Short answer: RTFM
--
Valentin Bonnard
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1999/11/08 Raw View
Yariv Saar wrote:
>
> Hi,
> I need do convert a wide-string variable into a char pointer, to be
> able to pass it as a parameter in GetPrivateProfileInt (for instance).
>
> What's the standard (STL) way of doing such a conversion?
I'm not completely sure what you want to do exactly.
One possibility would be that you have a wstring which in reality
only consists of characters which fit into a normal char. In that
case, the following should work (untested):
std::wstring source(whatever);
int const size = source.size;
char* destination = new char[size+1];
std::transform(source.begin(), source.end(),
destination, char_traits<wchar_t>::narrow);
destination[size]='\0';
GetPrivateProfileInt(destination); // or whatever the interface is
delete destination;
Another possibility would be that you want to do a specific
conversion (f.ex. UTF-16 to UTF-8). In that case, IMHO the
best solution would be an "iterator adapter" (untested
and incomplete):
template<class InputIterator> class utf16_to_utf8_iterator
{
typedef input_iterator_tag iterator_category;
typedef char value_type;
typedef ptrdiff_t difference_type;
typedef char* pointer;
typedef char& reference;
utf16_to_utf8_iterator(InputIterator i);
utf16_to_utf8_iterator& operator++();
utf16_to_utf8_iterator operator++(int);
char& operator*();
bool operator==(utf16_to_utf8_iterator const& other);
private:
InputIterator iter;
deque<char> chars;
};
template<class InputIterator>
utf16_to_utf8_iterator<InputIterator>::
utf16_to_utf8_iterator(InputIterator i):
iter(i)
{
}
template<class InputIterator>
utf16_to_utf8_iterator<class InputIterator>&
utf16_to_utf8_iterator<InputIterator>::operator++()
{
**this; // ensures that chars is not empty
chars.pop_front();
return *this;
**this; // ensures that chars is not empty
chars.pop_front();
return *this;
}
template<class InputIterator>
utf16_to_utf8_iterator<class InputIterator>
utf16_to_utf8_iterator<InputIterator>::operator++(int)
{
**this; // ensures that chars is not empty
chars.pop_front();
return *this;
}
template<class InputIterator>
char& utf16_to_utf8_iterator<InputIterator>::operator*()
{
if (chars.empty())
{
wchar_t nextchar = *iter++;
// add corresponding utf_8 byte(s) to chars (with push_back)
}
return chars.front();
}
template<class InputIterator>
bool utf16_to_utf8_iterator<InputIterator>::
operator==(utf16_to_utf8_iterator const& other)
{
return iter==other.iter && chars==other.chars;
}
template<class InputIterator>
utf16_to_utf8_iterator<InputIterator>
utf16_to_utf8(InputIterator i)
{
return utf16_to_utf8_iterator<InputIterator>(i);
}
Then the following would work:
std::wstring source(whatever);
string destination;
copy(utf16_to_utf8(source.begin()),
utf16_to_utf8(source.end()),
std::back_inserter(destination));
GetPrivateProfileInt(destination.c_str());
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]