std::locale::global是否影响printf()函数
Does std::locale::global make affect to printf() function?
我在电脑上使用俄语区域设置。
如果我设置:
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语言环境设置?
谢谢你的回答
但是,C的setlocale函数会对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.1en", 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=C;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_ruLC_CTYPE=ru_ru;LC_NUMERIC=C;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语言环境设置为与C++语言环境相同的"ru_ru"answers"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");
或类似的。
- 如何在类成员函数中获得类似printf中的编译警告
- 通过像printf这样的可变参数函数传递一个带有常量字符*转换函数的类
- C++ 如果 Printf 位于函数中,则返回是不同的
- 点在printf函数中是什么意思
- 为什么 printf 函数在以下代码中显示所需的输出
- 在VS2013与VS2017的printf函数中使用宏
- 为什么printf()函数打破了C中的指针adress
- 我可以从函数返回 printf 语句吗?C++
- std::locale::global是否影响printf()函数
- 显示类变量.在 printf 函数中使用字符串作为参数
- 当使用另一个函数封装 printf 和 vfprintf 时,这种差异的原因是什么?
- 为什么printf函数家族关心区域设置
- 错误地将字符串传递给printf样式的日志函数时缺少错误
- 从自定义 printf 函数返回一个常量字符*
- 如何正确地使模板运算符 T() 与 printf 等函数一起使用
- 无法解析 Eclipse C/C 函数'printf'
- printf 函数C++参数化前导零
- 当将数组传递给 printf 等可变参数函数时,我是否应该将数组转换为指针
- printf函数是如何工作的
- printf函数参数之间的序列点;转换之间的顺序点是否重要