如何在 MacOS 捆绑应用程序中使用 C++ std::locale?
How to use C++ std::locale in MacOS bundle application?
总结:似乎 C++ std::locale 函数仅在 MacOS 终端应用程序中工作正常,但在捆绑在 MacOS 应用程序包中时却不行。
我在 MacOS High Sierra 上编写了一个使用 C++17 std::locale 函数的 C++ 应用程序。
对于大多数程序,我需要已经设置好的默认 "C" 语言环境。但是对于特殊情况,我想设置 class 的流输出以使用系统区域设置。
当我从命令行 运行 但当我将应用程序打包到具有以下结构的 MacOS "application bundle" 时,它在测试时效果很好:
MyApp.app/Contents/MacOS/MyApp
那么它不能正常工作。
看起来好像在 MacOS 终端应用程序中设置的 LANG 环境变量没有为 MacOS 捆绑应用程序设置。
#include <iostream>
#include <fstream>
#include <sstream>
void test( std::ostream &output_, int test_, bool useLocale_, const std::string &expected_ )
{
int i = 1234;
std::stringstream ss;
if ( useLocale_ )
{
ss.imbue( std::locale( "" ) );
}
ss << i;
if ( ss.str( ) == expected_ )
{
output_ << "Test " << test_ << ": Passed" << std::endl;
}
else
{
output_ << "Test " << test_ << ": Expected '" << expected_ << "' but got '" << ss.str( ) << "'" << std::endl;
}
}
int main( )
{
std::ofstream output( "/Users/david/test.txt" );
test( output, 1, false, "1234" );
test( output, 2, true, "1,234" );
return 0;
}
预期结果(以及从 MacOs Terminal 运行ning 时获得的结果):
Test 1: Passed
Test 2: Passed
但是,双击 MacOS MyApp.app 图标时得到的结果:
Test 1: Passed
Test 2: Expected '1,234' but got '1234'
所以问题是:如何让 MacOS Bundle 应用程序将 LANG 环境变量设置为与 MacOS 终端应用程序使用的相同的东西,或者其他一些解决方法来完成同样的事情?
我花了几天时间在 Internet 上搜索答案并看到了一些相关问题,但 none 与我的问题直接匹配。
如何为 MacOS 捆绑应用程序设置 LANG 或以其他方式获取系统 LOCALE?
编辑:我做了一些更多的测试,问题是 LANG 环境变量没有在捆绑的应用程序上设置。
那么现在的问题可能归结为:如何在不设置LANG环境变量的情况下从MacOS系统获取LANG信息?
谢谢。
这解决了我的问题。
#ifdef __APPLE__
// MACOS needs a special routine to get the locale for bundled applications.
if ( getenv( "LANG" ) == nullptr )
{
const char *lang = get_mac_locale( );
setenv( "LANG", lang, 1 );
}
#endif
现在我的程序可以从 Apple Terminal 和作为捆绑应用程序正确运行。
总结:似乎 C++ std::locale 函数仅在 MacOS 终端应用程序中工作正常,但在捆绑在 MacOS 应用程序包中时却不行。
我在 MacOS High Sierra 上编写了一个使用 C++17 std::locale 函数的 C++ 应用程序。
对于大多数程序,我需要已经设置好的默认 "C" 语言环境。但是对于特殊情况,我想设置 class 的流输出以使用系统区域设置。
当我从命令行 运行 但当我将应用程序打包到具有以下结构的 MacOS "application bundle" 时,它在测试时效果很好:
MyApp.app/Contents/MacOS/MyApp
那么它不能正常工作。
看起来好像在 MacOS 终端应用程序中设置的 LANG 环境变量没有为 MacOS 捆绑应用程序设置。
#include <iostream>
#include <fstream>
#include <sstream>
void test( std::ostream &output_, int test_, bool useLocale_, const std::string &expected_ )
{
int i = 1234;
std::stringstream ss;
if ( useLocale_ )
{
ss.imbue( std::locale( "" ) );
}
ss << i;
if ( ss.str( ) == expected_ )
{
output_ << "Test " << test_ << ": Passed" << std::endl;
}
else
{
output_ << "Test " << test_ << ": Expected '" << expected_ << "' but got '" << ss.str( ) << "'" << std::endl;
}
}
int main( )
{
std::ofstream output( "/Users/david/test.txt" );
test( output, 1, false, "1234" );
test( output, 2, true, "1,234" );
return 0;
}
预期结果(以及从 MacOs Terminal 运行ning 时获得的结果):
Test 1: Passed
Test 2: Passed
但是,双击 MacOS MyApp.app 图标时得到的结果:
Test 1: Passed
Test 2: Expected '1,234' but got '1234'
所以问题是:如何让 MacOS Bundle 应用程序将 LANG 环境变量设置为与 MacOS 终端应用程序使用的相同的东西,或者其他一些解决方法来完成同样的事情?
我花了几天时间在 Internet 上搜索答案并看到了一些相关问题,但 none 与我的问题直接匹配。
如何为 MacOS 捆绑应用程序设置 LANG 或以其他方式获取系统 LOCALE?
编辑:我做了一些更多的测试,问题是 LANG 环境变量没有在捆绑的应用程序上设置。
那么现在的问题可能归结为:如何在不设置LANG环境变量的情况下从MacOS系统获取LANG信息?
谢谢。
这解决了我的问题。
#ifdef __APPLE__
// MACOS needs a special routine to get the locale for bundled applications.
if ( getenv( "LANG" ) == nullptr )
{
const char *lang = get_mac_locale( );
setenv( "LANG", lang, 1 );
}
#endif
现在我的程序可以从 Apple Terminal 和作为捆绑应用程序正确运行。