C++:服务器上的 boost::文件系统问题(区域设置::facet::_S_create_c_locale 名称无效



我在教职员工服务器上运行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());
}

该程序在另外两个基于 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

如果有人有任何想法要分享,我将不胜感激。

这是

Boost <1.56 的问题。 Boost 在内部尝试构建一个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;
  }
}

setenv调用后,我可以创建一个默认locale,并且boost::filesystem调用也可以工作。

我不确定,但我怀疑这个程序的行为是一样的:

#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 可能会对这个问题有所了解。

编辑:从技术上讲,这不是答案。

对于任何感兴趣的人,这里有一个使用QT-lib的上述目录迭代器版本:

string str1 = "ImageData/";
QString dir_string1 = QString::fromStdString(str1);
QString dir_string2 = QString::fromStdString(m_object_type);
dir_string1.append(dir_string2);
QDir dir(dir_string1);
dir.setFilter(QDir::Files);
dir.setSorting(QDir::Name); 
QStringList entries = dir.entryList();
string tmp;
for (QStringList::ConstIterator it=entries.begin(); it != entries.end(); ++it)
{
    auto name = *it;
    tmp = name.toUtf8().constData();
    image_names.push_back(str1 + m_object_type + "/" + tmp);
}

相关内容

最新更新