How to Initialize and Print a Std::Wstring

How to initialize and print a std::wstring?

To display a wstring you also need a wide version of cout - wcout.

std::wstring st = L"SomeText";
...
std::wcout << st;

why std::wofstream do not print all wstring into file?

A lot depends on the locale, but typically, files on disk will
not use the same encoding form (or even the same encoding) as
that used by wchar_t; the filebuf which does the actual
reading and writing translates the encodings according to its
imbued locale. And there is only a vague relationship between
the length of a string in different encodings or encoding form.
(And the size the system sees doesn't correspond directly to the
number of bytes you can read from the file.)

To see if everything was written, check the status of f
after the close, i.e.:

f.close();
if ( !f ) {
// Something went wrong...
}

One thing that can go wrong is that the external encoding
doesn't have a representation for one of the characters. If
you're in the "C" locale, this could occur for any character
outside of the basic execution character set.

If there is no error above, there's no reason off hand to assume
that not all of the string has been written. What happens if
you try to read it in another program? Do you get the same
number of characters or not?

For the rest, nul characters are characters like any others in
a std::wstring; there's nothing special about them, including
when they are output to a stream. And 18446744073709551615
looks very much like the value I would expect for
std::wstring::npos on a 64 bit machine.

EDIT:

Following up on Mat Petersson's comment: it's actually highly
unlikely that the file ends up with less bytes than there are
code points in the std::wstring. (std::wstring::size()
returns the number of code points.) I was thinking in terms of
bytes, not in terms of what std::wstring::size() returns. So
the most likely explination is that you have some characters in
your string which aren't representable in the target encoding
(which probably only supports characters with code points
32-126, plus a few control characters, by default).

How to construct WebURL from std::wstring?

WSLit is meant to construct a WebString object from an ASCII string. Since you don't want to construct a WebString from ASCII, but rather have a UNICODE string from the beginning, you simply don't need to use WSLit at all.

The following line of code constructs a WebURL from a std::wstring:

WebURL url(WebString(ui_path.c_str()));

As pointed out by Remy Lebeau this may not compile for any given compiler or compiler settings. WebString has an explicit constructor taking a const wchar16*. Platform.h defines wchar16 as

typedef unsigned short wchar16;

Depending on your compiler and compiler settings, this may or may not be the same as wchar_t. When compiling with the Microsoft compiler using the command line option /Zc:wchar_t, wchar_t is interpreted as a native data type. This is a different type from unsigned short, and the explicit constructor of WebString requires an additional cast:

WebURL url(WebString(reinterpret_cast<const wchar16*>(ui_path.c_str())));

Implicitly invoking the conversion constructor of WebString using the following syntax is not possible, since it is declared explicit:

WebURL url(reinterpret_cast<const wchar16*>(ui_path.c_str()));

How to convert wstring into string?

Here is a worked-out solution based on the other suggestions:

#include <string>
#include <iostream>
#include <clocale>
#include <locale>
#include <vector>

int main() {
std::setlocale(LC_ALL, "");
const std::wstring ws = L"ħëłlö";
const std::locale locale("");
typedef std::codecvt<wchar_t, char, std::mbstate_t> converter_type;
const converter_type& converter = std::use_facet<converter_type>(locale);
std::vector<char> to(ws.length() * converter.max_length());
std::mbstate_t state;
const wchar_t* from_next;
char* to_next;
const converter_type::result result = converter.out(state, ws.data(), ws.data() + ws.length(), from_next, &to[0], &to[0] + to.size(), to_next);
if (result == converter_type::ok or result == converter_type::noconv) {
const std::string s(&to[0], to_next);
std::cout <<"std::string = "<<s<<std::endl;
}
}

This will usually work for Linux, but will create problems on Windows.

Which part of boost library enables cout to print wstring and how?

boost::filesystem::path has an implicit conversion constructor from string_type, which is defined as std::basic_string<value_type>. And value_type is defined variably depending upon environment. Notably, wchar_t on Windows. Which means on Windows, string_type is std::basic_string<wchar_t>, a.k.a. std::wstring.

So your wstring is being implicitly converted to a boost::filesystem::path, which is overloaded for printing through operator<<.



Related Topics



Leave a reply



Submit