#c #boost #file-io
#c #boost #file-io
Вопрос:
пример кода на веб-сайте boost не работает. http://www.boost.org/doc/libs/1_46_1/libs/filesystem/v3/doc/tutorial.html#Using-path-decomposition
int main(int argc, char* argv[])
{
path p (argv[1]); // p reads clearer than argv[1] in the following code
try
{
if (exists(p)) // does p actually exist?
{
if (is_regular_file(p)) // is p a regular file?
cout << p << " size is " << file_size(p) << 'n';
else if (is_directory(p)) // is p a directory?
{
cout << p << " is a directory containing:n";
typedef vector<path> vec; // store paths,
vec v; // so we can sort them later
copy(directory_iterator(p), directory_iterator(), back_inserter(v));
sort(v.begin(), v.end()); // sort, since directory iteration
// is not ordered on some file systems
for (vec::const_iterator it (v.begin()); it != v.end(); it)
{
path fn = it->path().filename(); // extract the filename from the path
v.push_back(fn); // push into vector for later sorting
}
}
else
cout << p << " exists, but is neither a regular file nor a directoryn";
}
else
cout << p << " does not existn";
}
catch (const filesystem_erroramp; ex)
{
cout << ex.what() << 'n';
}
return 0;
}
два сообщения об ошибке при компиляции в Visual Studio 2010 для строки path fn = it->path().filename();
Первая ошибка: 'function-style cast' : illegal as right side of '->' operator
а вторая ошибка: left of '.filename' must have class/struct/union
Кроме того, когда я наведу курсор мыши на path (), он говорит: class boost::filesystem3::path Error: typename not allowed
Комментарии:
1. можете ли вы опубликовать URL, где вы нашли этот код?
2. пример кода здесь: boost.org/doc/libs/1_46_1/libs/filesystem/v3/doc /…
3. В какой-то момент произошло изменение в файловой системе boost. Заголовок должен был включать #define BOOST_FILESYSTEM_VERSION , где возвращаемый тип boost::filesystem::path::filename() изменен с версии boost 2 на 3. У меня есть некоторый код с #if #else, и в версии 3 вызовите .string(), чтобы обе версии соответствовали
Ответ №1:
Этот раздел ( for
тело) проблематичен:
path fn = it->path().filename(); // extract the filename from the path
v.push_back(fn); // push into vector for later sorting
it
указывает наpath
объекты, поэтому я не понимаю, почемуpath()
вызывается. Кажется, что его следует заменить наit->filename()
- вы помещаете имена файлов в конец одного и того же вектора, поэтому после цикла у вас будет вектор, содержащий список файлов дважды, сначала с путями, а затем просто с именами файлов.
РЕДАКТИРОВАТЬ: Глядя на исходный пример, я вижу, что это ваша модификация. Если вы хотите сохранить имена файлов вместо их печати, определите другой вектор string
или path
и сохраните в нем имена файлов, не используйте повторно первый. И удаление вызова path()
должно решить проблему компиляции.
ПРАВКА 2: кстати, вы можете выполнить как обход каталога, так и извлечение имени файла за один проход, используя std::transform
вместо std::copy
:
struct fnameExtractor { // functor
string operator() (pathamp; p) { return p.filename().string(); }
};
vector<string> vs;
vector<path> vp;
transform(directory_iterator(p), directory_iterator(), back_inserter(vs),
fnameExtractor());
То же самое использование mem_fun_ref
вместо fnameExtractor
функтора:
transform(directory_iterator(p), directory_iterator(), back_inserter(vp),
mem_fun_ref(amp;path::filename));
Комментарии:
1. Да, я, вероятно, должен был упомянуть, что я его изменил, но это код, который у них есть чуть ниже примера: «Ключевое различие между tut3.cpp и tut4.cpp это то, что происходит в цикле итерации каталога. Мы изменили:
cout << " " << *it << 'n';
на:path fn = it->path().filename(); v.push_back(fn);
»2. попробовал вашу правку 2 с функтором, и я получил это сообщение об ошибке:
No suitable user-defined conversion from "boost::filesystem3::path" to "std::string" exists.
3. чтобы решить это, поместите
return p.filename().string();
в функтор4. @ladookie — верно, я забыл об этом. Я отредактирую. Хотя я смутно помню, что в документе говорилось, что
path
определяет неявное преобразование вstd::string
…
Ответ №2:
После того, как вы разместили ссылку, кажется, что опубликованный код работает нормально. Но проблема возникает в измененном коде в for
цикле. первая проблема заключается в том, что path()
это конструктор. вторая проблема, я не уверен, что boost:: path содержит какой-либо метод как filename()
. Вы можете попробовать,
path fn = (*it);