Skip to content

<format>: The width of output is miscalculated when formatting a floating-point number in the locale-specific form #4316

@cpplearner

Description

@cpplearner

Describe the bug

Revealed by libc++ test std/utilities/format/format.functions/locale-specific_form.pass.cpp.

When formatting a floating-point number, digit separators are not taken into account when computing the width of output, which may cause too many fill characters in the output.

For integers, digit separators are correctly handled:

STL/stl/inc/format

Lines 2873 to 2878 in 3eac329

if (_Specs._Localized) {
_Groups = _STD use_facet<numpunct<_CharT>>(_Locale._Get()).grouping();
_Separators = _Count_separators(static_cast<size_t>(_End - _Buffer_start), _Groups);
// TRANSITION, separators may be wider for wide chars
_Width += _Separators;
}

For floating-point numbers, it seems that the width is not adjusted:

STL/stl/inc/format

Lines 3099 to 3102 in 3eac329

if (_Specs._Localized) {
_Groups = _STD use_facet<numpunct<_CharT>>(_Locale._Get()).grouping();
_Separators = _Count_separators(static_cast<size_t>(_Integral_end - _Buffer_start), _Groups);
}

Command-line test case

D:\test>type test-format.cpp
#include <format>
#include <iostream>

int main() {
    std::cout << std::format(std::locale("en_US"), "{:@>8L}\n", 12345);
    std::cout << std::format(std::locale("en_US"), "{:@>8L}\n", 12345.0);
}

D:\test>cl /std:c++20 /utf-8 /EHs test-format.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.39.33321 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

test-format.cpp
Microsoft (R) Incremental Linker Version 14.39.33321.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:test-format.exe
test-format.obj

D:\test>test-format.exe
@@12,345
@@@12,345

Expected behavior

The output should be @@12,345 instead of @@@12,345.

STL version

https://github.com/microsoft/STL/commit/3eac329d1f614ecf138d96c22a3b02f87076bc4a

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingfixedSomething works now, yay!formatC++20/23 format

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions