我有一个目前锁定在Visual Studio 2015中的项目.但是,我想编写符合标准的代码.
我想使用std::filesystem它,但直到C++ - 17才进入标准.幸运的是,几乎所有东西都可用,就在std::experimental::filesystem::v1命名空间中.我不喜欢一揽子using指令; 我更喜欢将事情做好,以明确事情的来源.所以我不打算在全球范围内using发表声明.需要一些魔法才能说服编译器按我的意愿行事.
这是我的第一次尝试:
#include <filesystem>
#if defined(_MSC_VER) && _MSC_VER <= 1900 // VS 2015
namespace std {
namespace filesystem {
using path = std::experimental::filesystem::v1::path;
}
}
#endif
Run Code Online (Sandbox Code Playgroud)
这很好用,std::filesystem::path现在可以访问.我测试了创建和使用path对象,它的工作原理.
随着我前进,我知道我将需要更多的东西.我想知道是否有办法引入整个事情:
namespace std {
namespace filesystem {
using std::experimental::filesystem::v1;
}
}
Run Code Online (Sandbox Code Playgroud)
这似乎是倒退了一步.似乎没有任何东西可见.事后来看,我认为这是有道理的,因为using语句的范围以下一行的右括号结束.
接下来,我想得到一个directory_entry.同样的技术似乎有效
namespace std {
namespace filesystem {
using directory_entry = std::experimental::filesystem::v1::directory_entry;
}
}
Run Code Online (Sandbox Code Playgroud)
再次,编译器似乎很高兴.
现在,我想用std::directory::create_directories.但是,这是一个函数,而不是一个类,所以相同的技术将无法工作.
我认为这std::function …
当我尝试将其std::filesystem::path用作函数参数时,它在我的计算机上出现段错误。这是一个最小的示例:
#include <filesystem>
void thing(const std::filesystem::path& p) {
return;
}
int main() {
thing("test");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
此代码段导致来自gdb的以下回溯:
#0 0x0000563a5a3814b3 in std::vector<std::filesystem::__cxx11::path::_Cmpt, std::allocator<std::filesystem::__cxx11::path::_Cmpt> >::~vector (this=0x23, __in_chrg=<optimized out>) at /usr/include/c++/8/bits/stl_vector.h:567
#1 0x0000563a5a38132c in std::filesystem::__cxx11::path::~path (this=0x3, __in_chrg=<optimized out>) at /usr/include/c++/8/bits/fs_path.h:208
#2 0x0000563a5a381f74 in std::filesystem::__cxx11::path::_Cmpt::~_Cmpt (this=0x3, __in_chrg=<optimized out>) at /usr/include/c++/8/bits/fs_path.h:643
#3 0x0000563a5a381f8f in std::_Destroy<std::filesystem::__cxx11::path::_Cmpt> (__pointer=0x3) at /usr/include/c++/8/bits/stl_construct.h:98
#4 0x0000563a5a381e3f in std::_Destroy_aux<false>::__destroy<std::filesystem::__cxx11::path::_Cmpt*> (__first=0x3, __last=0x0) at /usr/include/c++/8/bits/stl_construct.h:108
#5 0x0000563a5a381ab0 in std::_Destroy<std::filesystem::__cxx11::path::_Cmpt*> (__first=0x3, __last=0x0) at /usr/include/c++/8/bits/stl_construct.h:137
#6 0x0000563a5a3817c1 in std::_Destroy<std::filesystem::__cxx11::path::_Cmpt*, std::filesystem::__cxx11::path::_Cmpt> (__first=0x3, __last=0x0) at …Run Code Online (Sandbox Code Playgroud) 我有一台运行 El Capitan 版本 10.11.6 的旧 Mac(大约 2009 年)。Apple 不允许在我的机器上进一步更新其操作系统,但通过 Macports,它可以作为非 Apple 特定软件的良好开发环境。
我正在使用 g++ 9.2 进行编译,它支持开箱即用的 std::filesystem,而使用 clang 8.0 则不支持。(在每种情况下都使用每个编译器的本机标准库。)我正在使用 --std=c++2a 进行编译。
我注意到 llvm 9 应该支持开箱即用的 std::filesystem ( https://libcxx.llvm.org/docs/UsingLibcxx.html#using-filesystem ),所以我通过 Macports 下载了 clang/llvm 9 . 不幸的是,我遇到了障碍。
重现错误的最小代码是来自 cppreference.com ( https://en.cppreference.com/w/cpp/filesystem/path/path )示例的简化
#include <filesystem>
#include <iostream>
namespace fs = std::filesystem;
int
main()
{
fs::path p1 = "/usr/lib/sendmail.cf";
std::cout << "p1 = " << p1 << '\n';
}
Run Code Online (Sandbox Code Playgroud)
这是 CmakeLists.txt
cmake_minimum_required(VERSION 3.15.5)
project(bug LANGUAGES CXX)
add_executable (bug main.cpp)
target_compile_options(bug PRIVATE "-std=c++2a") …Run Code Online (Sandbox Code Playgroud) 如果我使用像absolute()我总是得到一个包含引号的路径的函数.
文件系统函数中是否有一种方法可以删除此引号,使其能够与std :: ifstream一起使用?
fs::path p2 { "./test/hallo.txt" };
std::cout << "absolte to file : " << fs::absolute(p2) << std::endl;
Run Code Online (Sandbox Code Playgroud)
收益:
Run Code Online (Sandbox Code Playgroud)"/home/bla/blub/./test/hallo.txt"
我需要
Run Code Online (Sandbox Code Playgroud)/home/bla/blub/./test/hallo.txt
代替.
手动执行它没有问题,但我想询问文件系统库中是否有方法.
这段代码中std::filesystem::copy()和之间有什么区别std::filesystem::copy_file()?
#include <filesystem>
void testing()
{
const std::filesystem::path src = "foo.txt";
const std::filesystem::path dst = "bar.txt";
std::filesystem::copy( src, dst, std::filesystem::copy_options::overwrite_existing);
std::filesystem::copy_file(src, dst, std::filesystem::copy_options::overwrite_existing);
}
Run Code Online (Sandbox Code Playgroud)
文档说:
copy():“复制文件或目录”copy_file():“复制文件内容”由于我在此示例中复制的是单个文件而不是目录,因此这两个调用是否相同?
(我使用的是 g++ 8.2.0。记住链接 libstdc++fs 否则你将有对 std::filesystem 的未定义引用。)
我试图包含<filesystem>,但是当我使用命名空间时,它显示此错误:
std:: 没有成员“文件系统”
我知道在以前是这样<experimental/filesystem>,命名空间是 std::experimental::filesystem;
但是,当我这样做时,它也会给出这样的错误:
#error The <experimental/filesystem> header providing std::experimental::filesystem is deprecated by Microsoft \
and will be REMOVED. It is superseded by the C++17 <filesystem> header providing std::filesystem. \
You can define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING to acknowledge that you have received this warning.
Run Code Online (Sandbox Code Playgroud)
我使用的是 Visual Studio 2019,C/C++ 语言设置设置为最新版本。
那么是什么原因导致了这个问题呢?
编辑1:导致错误的所有代码:
#include <iostream>
#include <Windows.h>
#include <filesystem>
namespace fs = std::filesystem;
int main() {
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编辑2:所有旧代码也有错误:
#include <iostream>
#include <Windows.h>
#include <experimental/filesystem>
namespace fs …Run Code Online (Sandbox Code Playgroud) 由于在 C++17 中std::filesystem::file_time_type使用了一个普通时钟,有没有办法检索file_time_typeC++17**的实际时钟类型?
目标是将时间转换为std::chrono::system_clock在流中使用它。
** 在 C++20 中,file_time_type将使用std::chrono::file_clock,它具有operator<<并且可以使用std::chrono::clock_cast.
我正在寻找递归复制文件夹而不会丢失文件和文件夹时间戳的简单方法。我觉得std::filesystem::copy很简单好用,但它把文件修改时间设置为现在。
我想std::filesystem在我的项目中使用,这将允许我显示.txt当前目录中的文件(我使用 Ubuntu,我不需要 Windows 函数,因为我已经在 StackOverflow 上看到了一个)。
这是我的 GitHub 存储库:
https://github.com/jaroslawroszyk/-how-many-pages-per-day
我有一个解决这个问题的方法,如下所示:
void showFilesTxt()
{
DIR *d;
char *p1, *p2;
int ret;
struct dirent *dir;
d = opendir(".");
if (d)
{
while ((dir = readdir(d)) != NULL)
{
p1 = strtok(dir->d_name, ".");
p2 = strtok(NULL, ".");
if (p2 != NULL)
{
ret = strcmp(p2, "txt");
if (ret == 0)
{
std::cout << p1 << "\n";
}
}
}
closedir(d);
}
}
Run Code Online (Sandbox Code Playgroud)
但是我在这里输入的代码想使用C++17,但我不知道如何找到文件.txt,现在我写道:
for (auto &fn …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用其insert(const_iterator pos, InputIt first, InputIt last)成员函数模板将转换后的目录条目范围插入向量中。不幸的是,我无法在 GCC 下编译以下代码,11.1.0根据https://en.cppreference.com/w/cpp/compiler_support应该有范围支持。
#include <filesystem>
#include <vector>
#include <ranges>
#include <iterator>
namespace fs = std::filesystem;
namespace ranges = std::ranges;
namespace views = std::views;
// no solution
namespace std {
template <typename F>
struct iterator_traits<ranges::transform_view<ranges::ref_view<fs::directory_iterator>, F>> {
using iterator_category = std::input_iterator_tag;
};
}
int main() {
std::vector<fs::path> directory_tree;
auto subdir = fs::directory_iterator(".");
ranges::input_range auto subdir_names = subdir
| views::transform([](const auto& entry) { return entry.path(); /* can be more complex*/ }) …Run Code Online (Sandbox Code Playgroud) c++ ×10
std-filesystem ×10
c++17 ×5
c++-chrono ×1
c++20 ×1
clang ×1
g++ ×1
gcc ×1
llvm ×1
std-ranges ×1
stdvector ×1
txt ×1