如何在 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 和作为捆绑应用程序正确运行。