Std::stringstream не работает после установки локали UTF8

У меня возникают проблемы с выводом чисел, когда я устанавливаю глобальную локаль в своем приложении C++. Вот пример рабочего кода:

#include <locale>
#include <clocale>
#include <sstream>
#include <iostream>

void initLocale() {
    constexpr char locale_name[] = "en_US.UTF-8";
    std::setlocale( LC_ALL, locale_name );
    std::locale::global(std::locale(locale_name));
}

int main() {
    int64_t i = -123434534536;
    std::stringstream s1;
    s1 << i << "\n";
    std::cout << "Before locale: " << s1.str();
    
    initLocale();
    
    std::stringstream s2;
    s2 << i << "\n";
    std::cout << "After locale: " << s2.str();
    
    return 0;
}

Я компилирую этот код в LINUX (debian) с помощью g++ с помощью этой команды:

g++ -std=c++17 -o test test.cpp

Результат, который я получаю при запуске программы, таков:

Before locale: -123434534536
After locale: -123,434,534,536

Почему std::stringstream ведет себя так после установки локали и как это исправить?

P.S.: Мне нужно использовать эту локаль, чтобы правильно обрабатывать символы, отличные от ANSI, в именах файлов (у меня есть файлы, содержащие китайские символы).

Вот как числа форматируются в локали США. Имена файлов не имеют ничего общего с локалью. (Вы путаете локаль с кодировкой символов?)

molbdnilo 11.04.2023 13:44

@molbdnilo Я знаю об этом, но установка этой локали была единственным способом заставить имена файлов правильно обрабатываться (долгая история) и выводиться на стандартный вывод. Есть ли способ использовать только кодировку без локали?

Bogdan Ionitza 11.04.2023 13:52
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

libstdc++ всегда реализовывал локали таким образом, и меня это тоже раздражало.

Самое простое решение — явно указать локаль "C" при форматировании числовых значений:

std::stringstream s2;

s2.imbue(std::locale{"C"});
s2 << i << "\n";

В зависимости от того, какие фактические операции форматирования вывода необходимы, вам может понадобиться изолировать весь отформатированный целочисленный вывод в их собственный std::ostream с пропитанной "C" локалью, а все остальное форматируется с использованием глобальной локали.

это, кажется, исправить это, большое спасибо!

Bogdan Ionitza 11.04.2023 14:14

Другие вопросы по теме