可以使用while(文件>>...C++成语在 Cython 中读取文件?
Can one use the while(file >> ...) C++ idiom to read files in Cython?
我想使用C++方式在Cython中读取文件。
我有一个简单的文件阅读器,看起来像这样:
std::ifstream file(fileName);
while(file >> chromosome >> start >> end >> junk >> junk >> strand)
{ ... }
我可以在Cython这样做吗?
可能更好的选择是使用 python 解析功能(例如 pandas' 或 numpy's(,或者,如果第一个解决方案不够灵活,则用纯C++对阅读器进行编码,然后从 Cython 调用该功能。
但是,您的方法在 Cython 中也是可能的,但为了使它起作用,需要跳过一些障碍:
- 整个
iostream
层次结构不是提供的libcpp包装器的一部分,因此必须包装它(如果没有,则快速和肮脏,那就是几行(。 - 由于
std::ifsteam
没有提供默认构造函数,因此我们无法将其构造为 Cython 中具有自动生存期的对象,并且需要注意内存管理。 - 另一个问题是使用定义的转换的包装。文档中没有很好地描述它(请参阅此 SO 问题(,但仅支持
operator bool()
]3,因此我们需要使用 C++11(否则operator void*() const;
(。
所以这里有一个快速和肮脏的概念证明:
%%cython -+ -c=-std=c++11
cdef extern from "<fstream>" namespace "std" nogil:
cdef cppclass ifstream:
# constructor
ifstream (const char* filename)
# needed operator>> overloads:
ifstream& operator>> (int& val)
# others are
# ifstream& operator>> (unsigned int& val)
# ifstream& operator>> (long& val)
# ...
bint operator bool() # is needed,
# so while(file) can be evaluated
def read_with_cpp(filename):
cdef int a=0,b=0
cdef ifstream* foo = new ifstream(filename)
try:
while (foo[0] >> a >> b):
print(a, b)
finally: # don't forget to call destructor!
del foo
实际上,operator>>(...)
的返回类型不是std::ifstream
而是std::basic_istream
- 我也懒得包装它。
现在:
>>> read_with_cpp(b"my_test_file.txt")
将文件内容打印到控制台。
但是,如上所述,我会用纯C++编写解析并从 Cython 使用它(例如,通过传递函子,因此 cpp 代码可以使用 Python 功能(,这是一个可能的实现:
%%cython -+
cdef extern from *:
"""
#include <fstream>
void read_file(const char* file_name, void(*line_callback)(int, int)){
std::ifstream file(file_name);
int a,b;
while(file>>a>>b){
line_callback(a,b);
}
}
"""
ctypedef void(*line_callback_type)(int, int)
void read_file(const char* file_name, line_callback_type line_callback)
# use function pointer to get access to Python functionality in cpp-code:
cdef void line_callback(int a, int b):
print(a,b)
# expose functionality to pure Python:
def read_with_cpp2(filename):
read_file(filename, line_callback)
现在调用read_with_cpp2(b"my_test_file.txt")
会导致与上述相同的结果。
相关文章:
- .cpp和.h文件中的模板专用化声明
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 文本文件中的单词链表
- CMake-按正确顺序将项目与C运行时对象文件链接
- 使用新行和不使用新行读取文件
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 挂起和取消挂起一个文件DLL
- 如何确定我已使用非编码文件到达 EOF?
- 命名空间中具有.h和.cpp文件的类
- 如何使用ndk-build.cmd构建Android.so文件
- 从包含m行的文件中提取n行,必要时(惰性地)重复该文件
- 读取文件并输入到矢量中
- 在C++中查找文件
- c++库的公共头文件中应该包含什么
- 用c++从输入文件中读取另一行
- Cppcheck生成xml转储文件
- 读取文件的最后一行并输入到链接列表时出错
- 无法编译 rtmidi 测试 cmidiin.cpp 文件, 非法指令
- 如何将内容数组写入文本文件?
- C++ Windows 驱动程序MSB3030无法复制该文件,因为它找不到