- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试围绕 c header dirent.h 编写一个现代 c++ 包装器。
在C中要读取一个目录的内容,写成类似下面的内容:
int listdir(const char *path) {
struct dirent *entry;
DIR *dp;
dp = opendir(path);
if (dp == NULL) {
perror("opendir");
return -1;
}
while((entry = readdir(dp)))
puts(entry->d_name);
closedir(dp);
return 0;
}
将其转换为现代 C++,我有以下内容(其中 m_dir 和 m_dirent 是 std::unique_ptr
的,而 m_files 是 std::vector<string>
)
filesystem::Directory::Directory(std::string dir) : m_dir(opendir(dir.c_str()), closedir),
m_dirent(new struct dirent())
{
//If the directory can not be read, throw an error.
if (!m_dir) {
sdl2::SDLFileSystemRead_Failure ex;
throw ex;
}
while (&(*m_dirent = *readdir(&*m_dir)))
{
m_files.emplace_back(std::string(m_dirent->d_name));
}
}
这只成功了一半。当我写它的时候,我没有注意到我只是在检查表达式的地址 *m_dirent = *readdir(&*m_dir)
存在(当然它确实存在!)。根据The Single UNIX ® Specification, Version 2 , readdir(DIR*) 如果它已经读取了最后一个文件并且没有更多的文件要读取,则返回一个空指针。但是,我不确定如何在不调用 .reset()
的情况下将 dirent 指针设置为 dir 指针正在读取的内容。在 m_dirent
.但是,这样做只会导致读取垃圾数据,因为我假设文件指针在 dirent
时丢失了。被摧毁。
我如何转换它
while((entry = readdir(dp)))
puts(entry->d_name);
进入现代 C++?
最佳答案
我不确定这算不算是现代,因为我在上个千年在 UseNet 上发布了类似的内容(here 是精炼版)。它略有进化,成为最早用于播种的成分之一 Boost 1998 年。由于其他人的工作,它在 Boost 得到了进一步发展,并最终变成了 file system library。这构成了File System TS的基础.
然而,这一切都始于一个简单的想法:如何很好地公开 opendir()
、readdir()
和 closedir()
?有点明显的答案是:使用迭代器!这是一个简单的版本和演示:
#include <iostream>
#include <iterator>
#include <algorithm>
#include <string>
#include <stdexcept>
#include <memory>
#include <dirent.h>
class dir_it
: public std::iterator<std::input_iterator_tag, std::string>
{
std::shared_ptr<DIR> dir;
std::string current;
void advance() {
dirent entry;
dirent* result;
if (!readdir_r(dir.get(), &entry, &result) && result) {
this->current = result->d_name;
}
else {
this->dir.reset();
}
}
public:
dir_it(std::string const& path)
: dir(opendir(path.c_str()), [](DIR* dir){ dir && closedir(dir); }) {
if (!dir) {
throw std::runtime_error("failed to open directory '" + path + "'");
}
this->advance();
}
dir_it(): dir() {}
std::string const& operator*() const { return this->current; }
dir_it& operator++() { this->advance(); return *this; }
dir_it operator++(int) {
dir_it rc(*this);
this->operator++();
return rc;
}
bool operator==(dir_it const& other) const {
return bool(this->dir) == bool(other.dir);
}
bool operator!=(dir_it const& other) const {
return !(*this == other);
}
};
int main() {
std::copy(dir_it("."), dir_it(), std::ostream_iterator<std::string>(std::cout, "\n"));
}
当然,Boost 和文件系统 TS 中的文件系统库比这个有点幼稚的实现多更强大。如果您的实现附带了 TS 的实现,我会使用它。如果不是,您可能需要考虑 Boost 的实现。
关于c++ - 围绕 C Dirent.h 的现代 C++ 包装器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31975501/
我之前让 dll 注入(inject)器变得简单,但我有 Windows 7,我用 C# 和 C++ 做了它,它工作得很好!但是现在当我在 Windows 8 中尝试相同的代码时,它似乎没有以正确的方
我正在尝试制作一个名为 core-splitter 的元素,该元素在 1.0 中已弃用,因为它在我们的项目中起着关键作用。 如果您不知道 core-splitter 的作用,我可以提供一个简短的描述。
我有几个不同的蜘蛛,想一次运行所有它们。基于 this和 this ,我可以在同一个进程中运行多个蜘蛛。但是,我不知道如何设计一个信号系统来在所有蜘蛛都完成后停止 react 器。 我试过了: cra
有没有办法在达到特定条件时停止扭曲 react 器。例如,如果一个变量被设置为某个值,那么 react 器应该停止吗? 最佳答案 理想情况下,您不会将变量设置为一个值并停止 react 器,而是调用
https://code.angularjs.org/1.0.0rc9/angular-1.0.0rc9.js 上面的链接定义了外部js文件,我不知道Angular-1.0.0rc9.js的注入(in
我正在尝试运行一个函数并将服务注入(inject)其中。我认为这可以使用 $injector 轻松完成.所以我尝试了以下(简化示例): angular.injector().invoke( [ "$q
在 google Guice 中,我可以使用函数 createInjector 创建基于多个模块的注入(inject)器。 因为我使用 GWT.create 在 GoogleGin 中实例化注入(in
我在 ASP.NET Core 1.1 解决方案中使用配置绑定(bind)。基本上,我在“ConfigureServices Startup”部分中有一些用于绑定(bind)的简单代码,如下所示: s
我在 Spring MVC 中设置 initBinder 时遇到一些问题。我有一个 ModelAttribute,它有一个有时会显示的字段。 public class Model { privat
我正在尝试通过jquery post发布knockoutjs View 模型 var $form = $('#barcodeTemplate form'); var data = ko.toJS(vm
如何为包含多态对象集合的复杂模型编写自定义模型绑定(bind)程序? 我有下一个模型结构: public class CustomAttributeValueViewModel { publi
您好,我正在尝试实现我在 this article 中找到的扩展方法对于简单的注入(inject)器,因为它不支持开箱即用的特定构造函数的注册。 根据这篇文章,我需要用一个假的委托(delegate)
你好,我想自动注册我的依赖项。 我现在拥有的是: public interface IRepository where T : class public interface IFolderReposi
我正在使用 Jasmine 测试一些 Angular.js 代码。为此,我需要一个 Angular 注入(inject)器: var injector = angular.injector(['ng'
我正在使用 Matlab 代码生成器。不可能包含代码风格指南。这就是为什么我正在寻找一个工具来“ reshape ”、重命名和重新格式化生成的代码,根据我的: 功能横幅约定 文件横幅约定 命名约定 等
这个问题在这里已经有了答案: Where and why do I have to put the "template" and "typename" keywords? (8 个答案) 关闭 8
我开发了一种工具,可以更改某些程序的外观。为此,我需要在某些进程中注入(inject)一个 dll。 现在我基本上使用这个 approach .问题通常是人们无法注入(inject) dll,因为他们
我想使用 swing、spring 和 hibernate 编写一个 java 应用程序。 我想使用数据绑定(bind)器用 bean 的值填充 gui,并且我还希望它反射(reflect) gui
我有这段代码,当两个蜘蛛完成后,程序仍在运行。 #!C:\Python27\python.exe from twisted.internet import reactor from scrapy.cr
要点是 Spring Batch (v2) 测试框架具有带有 @Autowired 注释的 JobLauncherTestUtils.setJob。我们的测试套件有多个 Job 类提供者。因为这个类不
我是一名优秀的程序员,十分优秀!