gpt4 book ai didi

c++ - 多次调用 setlocale

转载 作者:行者123 更新时间:2023-12-03 09:47:17 24 4
gpt4 key购买 nike

我想弄清楚 C++ 是如何支持 Unicode 的。
当我想将多语言文本输出到控制台时,我调用 std::setlocale .但是我注意到结果取决于之前对 setlocale 的调用.
考虑以下示例。如果不带参数运行它会调用 setlocale一次,否则它会预先调用 setlocale获取当前语言环境的值并在函数结束时恢复它。

#include <iostream>
#include <locale>

using namespace std;

int main(int argc, char** argv)
{
char *current_locale = 0;

if (argc > 1) {
current_locale = setlocale(LC_ALL, NULL);
wcout << L"Current output locale: " << current_locale << endl;
}

char* new_locale = setlocale(LC_ALL, "ru_RU.UTF8");
if (! new_locale)
wcout << L"failed to set new locale" << endl;
else
wcout << L"new locale: " << new_locale << endl;


wcout << L"Привет!" << endl;

if (current_locale) setlocale(LC_ALL, current_locale);
return 0;
}
输出不同:
:~> ./check_locale 
new locale: ru_RU.UTF8
Привет!
:~> ./check_locale 1
Current output locale: C
new locale: ru_RU.UTF8
??????!
有没有什么 setlocale(LC_ALL, NULL)以后需要处理吗 setlocale电话?
编译器是 g++ 7.5.0clang++ 7.0.1 .控制台是图形终端中的 linux 控制台。
有关系统配置的更多详细信息:OpenSUSE 15.1、linux 4.12、glibc 2.26、libstdc++6-10.2.1

最佳答案

Is there something that setlocale(LC_ALL, NULL) does that needs to be taken care of in future setlocale calls?


不, setlocale(..., NULL)不修改当前语言环境。下面的代码很好:
setlocale(LC_ALL, NULL);
setlocale(LC_ALL, "ru_RU.UTF8");
wprintf(L"Привет!\n");
但是下面的代码会失败:
wprintf(L"anything"); // or even just `fwide(stdout, 1);`
setlocale(LC_ALL, "ru_RU.UTF8");
wprintf(L"Привет!\n");
问题是流有它自己的区域设置,在流方向更改为宽时确定。
// here stdout has no orientation and no locale associated with it
wprintf(L"anything");
// `stdout` stream orientation switches to wide stream
// current locale is used - `stdout` has C locale

setlocale(LC_ALL, "ru_RU.UTF8");
wprintf(L"Привет!\n");
// `stdout` is wide oriented
// current locale is ru_RU.UTF-8
// __but__ the locale of `stdout` is still C and cannot be changed!
我找到的唯一文档 gnu.org Stream and I18N强调我的:

Since a stream is created in the unoriented state it has at that point no conversion associated with it. The conversion which will be used is determined by the LC_CTYPE category selected at the time the stream is oriented. If the locales are changed at the runtime this might produce surprising results unless one pays attention. This is just another good reason to orient the stream explicitly as soon as possible, perhaps with a call to fwide.


你可以:
  • 对 C++ 流和 C 使用单独的语言环境 FILE (见 here):
  • std::ios_base::sync_with_stdio(false);
    std::wcout.imbue(std::locale("ru_RU.utf8"));
  • 重开 stdout :
  • wprintf(L""); // stdout has C locale
    char* new_locale = setlocale(LC_ALL, "ru_RU.UTF8");
    freopen("/dev/stdout", "w", stdout); // stdout has no stream orientation
    wprintf(L"Привет!\n"); // stdout is wide and ru_RU locale
  • 我认为(未经测试)在 glibc 中你甚至可以重新打开 stdout使用明确的语言环境(参见 GNU opening streams ):
  • freopen("/dev/stdout", "w,css=ru_RU.UTF-8", stdout);
    std::wcout << L"Привет!\n"; // fine
  • 无论如何,在做任何其他事情之前,尽快尝试设置语言环境。
  • 关于c++ - 多次调用 setlocale,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65166777/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com