Я использую настройки русского языка на моем ПК.
Если бы я установил:
class numpunct_withpoint: public numpunct<char>
{
protected:
/// Override the function that gives the decimal separator.
char do_decimal_point() const
{
return '.';
}
};
...
locale loc(std::locale::classic(), new numpunct_withpoint);
std::locale::global(loc);
и тогда
printf("%f", 3.14);
Выход:
3,14
Десятичный разделитель — «,» не так, как в функции do_decimal_point!
Как я могу изменить настройки языка C для десятичного разделителя с языком C ++?
Спасибо за ответ!
Но влияет ли функция setlocale на C на объект Cout c ++?
setlocale(LC_NUMERIC, "C");
Повлияет ли это на печать десятичного значения через cout?
Когда вы устанавливаете глобальный языковой стандарт C ++, языковой стандарт C также изменяется. Если вы измените языковой стандарт C, глобальный языковой стандарт C ++ не является модифицирована.
Ниже демонстрируется настройка глобальной локали C ++.
#include <cstdio>
#include <clocale>
#include <fstream>
int main() {
const char * locale_name = "French_France.1252"; // or "fr_Fr.UTF-8" on Unix
double value = 1.2;
std::locale::global(std::locale(locale_name));
std::ofstream("out.txt") << "C++ " << value << '\n';
if (FILE *f = std::fopen("out.txt", "a")) {
std::fprintf(f, "C %1.1e\n", value);
std::fclose(f);
}
}
Для вывода как на C, так и на C ++ следует использовать десятичную запятую.
C ++ 1,2
C 1,2e + 000
Если вы замените настройку языка C ++ на настройку языка C, std::setlocale(LC_ALL, locale_name);
, тогда выходные данные должны измениться так, чтобы только выходные данные C использовали десятичную запятую, в то время как выходные данные C ++ все еще использовали десятичный символ периода по умолчанию.
C ++ 1.2
C 1,2e + 000
Однако тот факт, что установка языкового стандарта C ++ влияет на языковой стандарт C, не делает расширяемые языковые стандарты C такими же, какими являются языковые стандарты C ++. Пользовательские фасеты C ++ никогда не будут использоваться функциями, основанными на локали C. Вместо этого вы должны полагаться на свою систему, поддерживающую некоторую именованную локаль, обладающую необходимой вам функциональностью.
В частности, std::locale::global()
определяется для установки языкового стандарта C с использованием имени выбранного языкового стандарта C ++, если у него есть имя. Поведение определяется реализацией, если у локали C ++ нет имени. Кроме того, C ++ указывает, что объединение двух именованных локалей создает именованную локаль. Некоторые реализации создают полезные комбинированные имена, которые позволяют смешивать категории языковых стандартов C, просто устанавливая языковой стандарт C ++:
std::locale::global(std::locale(std::locale("ru_RU"), "C", std::locale::numeric));
С libstdc ++ это производит локаль с именем:
LC_CTYPE = ru_RU; LC_NUMERIC = С; LC_TIME = ru_RU; LC_COLLATE = ru_RU; LC_MONETARY = ru_RU; LC_MESSAGES = ru_RU; LC_PAPER = ru_RU; lc_name = ru_RU; LC_ADDRESS = ru_RU; LC_TELEPHONE = ru_RU; LC_MEASUREMENT = ru_RU; LC_IDENTIFICATION = ru_RU
LC_CTYPE = ru_RU; LC_NUMERIC = С; LC_TIME = ru_RU; LC_COLLATE = ru_RU; LC_MONETARY = ru_RU; LC_MESSAGES = ru_RU; LC_PAPER = ru_RU; lc_name = ru_RU; LC_ADDRESS = ru_RU; LC_TELEPHONE = ru_RU; LC_MEASUREMENT = ru_RU; LC_IDENTIFICATION = ru_RU
Так что языковой стандарт C устанавливается в той же смеси между языковыми стандартами «ru_RU» и «C», что и языковой стандарт C ++.
К сожалению, другие реализации выбирают менее полезное, хотя и технически совместимое поведение. В Visual Studio
std::locale::global(std::locale(std::locale("Russian_Russia.1251"), "C", std::locale::numeric));
производит локаль с именем «C». Таким образом, в то время как языковой стандарт C ++ представляет собой подходящую смесь категорий русского языка и языка C, языковой стандарт C просто устанавливается на «C». Таким образом, на этих платформах для смешивания категорий локали C вы должны напрямую установить локаль C:
// set the C++ locale first
std::locale::global(std::locale(std::locale("Russian_Russia.1251"), "C", std::locale::numeric));
// set the C locale second, because it will not overwrite the changes you made to the C++ locale
std::setlocale(LC_ALL, "Russian_Russia.1251");
std::setlocale(LC_NUMERIC, "C");
Библиотека C не использует те же настройки локали, что и C ++. Для переопределения локали, используемой printf
использовать Setlocale:
setlocale(LC_NUMERIC, "POSIX");
или похожие.