1

教職員のサーバーで C++ プロジェクトを実行する際に問題があります。私が得る実行時エラーはこれです:

terminate called after throwing an instance of 'std::runtime_error'
what():  locale::facet::_S_create_c_locale name not valid
Aborted (core dumped)

私は、問題がこのファイルシステム イテレータのどこかにあると判断しました (テスト プログラムを利用することにより)。

bf::path dir("ImageData/" + m_object_type);

vector<bf::path> tmp;
copy(bf::directory_iterator(dir), bf::directory_iterator(), back_inserter(tmp));
sort(tmp.begin(), tmp.end());
for (vector<bf::path>::const_iterator it(tmp.begin()); it != tmp.end(); ++it)
{
    auto name = *it;
    image_names.push_back(name.string());
}

このプログラムは、他の 2 つの Linux ベースのシステム (kubuntu と linux mint で実行しましたが、私のプロジェクトは実行時間が非常に長く、別のパラメーターで実行すると、私のマシンで約 28 日かかるため、実際にサーバーを使用したいと考えています) で完全に実行されました。すでにさまざまな方法を試しましたが、どれもうまくいきませんでした。1.47 より前にこのエラーを引き起こしたブースト バグについて読みましたが、サーバーでは 1.54 を使用しています。システム ロケールも確認しましたが、私のシステムとほぼ同じであるため、実際には手がかりが得られませんでした。サーバーのその他の仕様は次のとおりです。

Ubuntu 12.04.1 LTS (GNU/Linux 3.2.0-29-generic x86_64) g/c++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3

誰かが共有するアイデアを持っているなら、私はそれを感謝します.

4

3 に答える 3

2

これはBoost < 1.56 の問題です。Boost は内部的に a を構築しようとしますstd::locale("")( http://www.boost.org/doc/libs/1_55_0/libs/filesystem/src/path.cppを参照し、 v1.56の更新されたバージョンを比較してください)。ロケール (またはLC_ALL) が無効な場合、この呼び出しは失敗します。

私の場合、呼び出しをboost::filesystem::create_directories()トリガーしたのはへのlocale("")呼び出しでした。

LC_ALL次の回避策がうまくいきました。プログラムで環境変数を オーバーライドします。std::locale("")その変数を使用して、「適切なデフォルト」ロケールを決定しているようです。

#include <locale>
#include <cstdlib>
#include <iostream>

int main(int argc, char **)
{
  try {
    std::locale loc("");
    std::cout << "Setting locale succeeded." << std::endl;
  } catch (const std::exception& e) {
    std::cout << "Setting locale failed: " << e.what() << std::endl;
  }

  // Set LC_ALL=C, the "classic" locale
  setenv("LC_ALL", "C", 1);
  // Second attempt now works for me:
  try {
    std::locale loc("");
    std::cout << "Setting locale succeeded." << std::endl;
  } catch (const std::exception& e) {
    std::cout << "Setting locale failed: " << e.what() << std::endl;
  }
}

呼び出しの後、setenvdefault を作成できlocaleboost::filesystem呼び出しも同様に機能します。

于 2016-08-26T13:52:13.550 に答える
-1

確かなことはわかりませんが、このプログラムも同じように動作すると思われます。

#include <locale>
#include <iostream>
#include <stdexcept>

int main () {
    try { std::locale foo (""); }
    catch ( std::runtime_error & ex ) { std::cout << ex.what() << std::endl; }  
    }

また、この (古い) チケットhttps://svn.boost.org/trac/boost/ticket/5289は、この件に光を当てるかもしれません。

編集: 技術的には、これは答えではありません。

于 2013-10-16T14:36:03.240 に答える