public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug libstdc++/115064] New: Possible problem with money_put
@ 2024-05-13  7:14 lcarreon at bigpond dot net.au
  0 siblings, 0 replies; only message in thread
From: lcarreon at bigpond dot net.au @ 2024-05-13  7:14 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115064

            Bug ID: 115064
           Summary: Possible problem with money_put
           Product: gcc
           Version: 14.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: lcarreon at bigpond dot net.au
  Target Milestone: ---

I have been experimenting with std::money_put and discovered the following:

#include <locale>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <format>

int main()
{
  std::locale loc{std::locale{"de_DE.utf8"}};
  std::cout.imbue(loc);

  auto money = 123456789.0L;

  {
    const auto& money_put =
std::use_facet<std::money_put<char>>(std::cout.getloc());
    std::cout << "\"" << std::showbase << std::setw(20) << std::right;
    money_put.put(std::cout, false, std::cout, '*', money);
    std::cout << "\"" << std::endl;
  }

  {
    std::ostringstream str;
    str.imbue(loc);
    const auto& money_put = std::use_facet<std::money_put<char>>(str.getloc());
    str << std::showbase << std::setw(20) << std::right;
    money_put.put(str, false, str, '*', money);
    str << std::endl;
    for (const auto& ch : str.str())
    {
      std::cout << std::format("{:02x} ", ch);
    }
    std::cout << std::endl;
  }

  return 0;
}

I compiled the above program using g++ 14.0.1 using c++20 mode. When I execute
the program on a terminal whose LANG is set to en_AU.utf8, I get the following
result:

"****1.234.567,89*€"
2a 2a 2a 2a 31 2e 32 33 34 2e 35 36 37 2c 38 39 2a e2 82 ac 0a

The first line above is the problematic one because it shows only 18 characters
inside the double quotes instead of 20.  The second line above explains why. 
The euro symbol is made up of three octets which is upsetting std::setw(20).

I revised the above program using wchar_t and std::wcout as follows:

#include <locale>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <format>

int main()
{
  std::locale loc{std::locale{"de_DE.utf8"}};
  std::wcout.imbue(loc);

  auto money = 123456789.0L;

  {
    const auto& money_put =
std::use_facet<std::money_put<wchar_t>>(std::wcout.getloc());
    std::wcout << L"\"" << std::showbase << std::setw(20) << std::right;
    money_put.put(std::wcout, false, std::wcout, L'*', money);
    std::wcout << L"\"" << std::endl;
  }

  {
    std::wostringstream str;
    str.imbue(loc);
    const auto& money_put =
std::use_facet<std::money_put<wchar_t>>(str.getloc());
    str << std::showbase << std::setw(20) << std::right;
    money_put.put(str, false, str, L'*', money);
    str << std::endl;
    for (const auto& ch : str.str())
    {
      std::wcout << std::format(L"{:02x} ", static_cast<unsigned>(ch));
    }
    std::wcout << std::endl;
  }

  return 0;
}

Executing the above program on the same terminal, I get the following:

"******1.234.567,89*EUR"
2a 2a 2a 2a 2a 2a 31 2e 32 33 34 2e 35 36 37 2c 38 39 2a 20ac 0a

The first line above now has 22 characters instead of 20.  The second line
above shows what characters were sent to the terminal.  It seems the euro
symbol "20ac" is displayed by the terminal as "EUR" instead of the single glyph
"€".

I understand that the terminal is set for UTF-8, thus the correct display of
the euro symbol in char mode.  But why display "EUR" in wchar_t mode?

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2024-05-13  7:14 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-05-13  7:14 [Bug libstdc++/115064] New: Possible problem with money_put lcarreon at bigpond dot net.au

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).