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());
}

该程序在另外两个基于 Linux 的系统上完美运行(kubuntu 和 linux mint,但由于我的项目运行时非常繁重,并且在我的机器上使用不同的参数运行它大约需要 28 天,我真的想使用服务器)。我已经尝试了各种路径,但都没有奏效。我读到了一个在 1.47 之前导致这个错误的 boost 错误,但我在服务器上使用的是 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 在内部尝试构建一个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,我可以创建一个 default locale,并且boost::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 回答
-1

对于任何感兴趣的人,这里是使用 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);
}
于 2013-10-17T15:33:24.317 回答