New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
<locale>: Creating a new locale with a custom facet doesn't work correctly #245
Comments
@connex-nachtschatten, if you're still interested in this issue, could you clarify your example? It doesn't actually use any facets, so it's not clear what, if anything, is going wrong. It would be better to avoid examining the console output, because it depends on system-specific things like the active code page. The example below, comparing the raw strings, works for me. You can see that it's a mix of German-style number and US-style money formatting. C:\temp>type gh-245.cpp
#include <cassert>
#include <iomanip>
#include <locale>
#include <sstream>
using namespace std;
int main() {
std::locale loc(locale{"de-DE.utf-8"}, "en-US.utf-8", locale::monetary);
std::stringstream ss;
ss.imbue(loc);
ss << 1234 << ' ' << std::showbase << std::put_money(567);
assert(ss.str() == "1.234 $5.67");
return 0;
}
C:\temp>cl /EHsc /std:c++latest /nologo gh-245.cpp
gh-245.cpp
C:\temp>.\gh-245.exe
C:\temp> |
the problem is real the output in console for this example.
I used as global locale in line(1) the object loc_ger. output is:
Now I use the object from line(2) which is the locale loc_ger with the facet from loc_en.
but the result is different:
An other example is with an own ctype facet. The problem is that the mask table for ctype::is is incorrect.
the output is
To fix that problem I made my own table:
then I made a little test
here I use a german locale and combine it with by own ctype facet. The result of the test is
The first 0 is from isblank function. BTW: if I changefor std::cout the locale to "de" I can´t write umlauts(öäü). It works only with the global locale. Is there an other way to write umlauts to concole without set std::locale::globale to "de"? |
There seems to be a couple different issues going on, let me take them one by one.
C:\temp>type temp.cpp
#include <array>
#include <iostream>
#include <locale>
using namespace std;
template <class CHAR_TYPE, size_t SIZE>
inline constexpr auto fix_blank_category(array<CHAR_TYPE, SIZE>& table) noexcept -> void {
for (size_t i = 0; i < SIZE; ++i) {
if (table[i] & ctype_base::blank) {
table[i] = table[i] & ~(ctype_base::blank); // delete blank bit
}
}
table[' '] |= ctype_base::blank;
table['\t'] |= ctype_base::blank;
}
struct fixed_blank_ctype : ctype<char> {
fixed_blank_ctype(void) : ctype<char>(table()) {}
static auto table(void) noexcept -> const ctype_base::mask* {
static array<ctype_base::mask, 256> s_table;
fix_blank_category(s_table);
return s_table.data();
}
}; /* struct fixed_blank_ctype */
inline auto fixed_blank_locale(const locale& loc) noexcept -> locale {
return locale(loc, new fixed_blank_ctype());
}
inline auto fixed_blank_locale(const char* loc_name) -> locale {
return fixed_blank_locale(locale(loc_name));
}
int main() {
cout << isblank('\n', cout.getloc()) << endl;
locale loc_fix_blank(cout.getloc(), new fixed_blank_ctype);
cout.imbue(loc_fix_blank);
cout << isblank('\n', cout.getloc()) << endl;
}
C:\temp>cl /std:c++latest /nologo /EHsc temp.cpp
temp.cpp
C:\temp>.\temp.exe
1
0
C:\temp>
Note that this refers to the C locale, not the C++ locale or the one associated with the stream. These points together explain the behavior you observe.
As for your final question, "Is there an other way to write umlauts to console without set std::locale::global to 'de'?", I hesitate to answer because I'm far from an expert, and I don't want to mislead you. But some methods I've observed to work are (1) call |
@MattStephanson is right.
|
Describe the bug
I tried to make a workaround to solve an old bug in STL, which isn't fixed after some years :(
(DevCom-51443).
Just created a ctype facet with an own table. But when I create a new locale with my custom facet, the locale change from german to classic (i think it's classic locale). For simplicity i add in demo code std::money_get facet instead of my custom ctype facet, but it's the same behaviour.
I´m using VS2019 with latest update (16.3.7)
output shall be:
"üöäÜÖÄ"
but output is:
"³÷õ▄Í─"
I did the same test on https://rextester.com/l/cpp_online_compiler_gcc. there i got the correct output.
Greets from germany
Helmut
The text was updated successfully, but these errors were encountered: