- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在cython 中写了一个class
,它使用c++ 中的vector
来创建两个-维数组。我当前的问题是,我想将数组/矩阵的内容写入
和读取
到来自文本文件。我想让矩阵的每一行都写在同一行中。我还想知道如何为每个书面值指定一个格式
?
矩阵.pyx
from libcpp.vector cimport vector
import cython
import numpy as np
import ctypes
cimport numpy as np
cimport cython
from libcpp.string cimport string
cdef extern from "<iostream>" namespace "std" nogil:
cdef cppclass ostream:
ostream& write(const char*, int) except +
cdef cppclass istream:
istream& read(const char*, int) except +
cdef cppclass ifstream(istream):
ifstream(const char *) except +
cdef extern from "<fstream>" namespace "std" nogil:
cdef cppclass filebuf:
pass
cdef cppclass fstream:
void close()
bint is_open()
void open(const char*, openmode)
void open(const char&, openmode)
filebuf* rdbuf() const
filebuf* rdbuf(filebuf* sb)
cdef cppclass ofstream(ostream):
ofstream(const char*) except +
ofstream(const char*, openmode) except+
cdef cppclass ifstream(istream):
ifstream(const char*) except +
ifstream(const char*, openmode) except+
cdef extern from "<iostream>" namespace "std::ios_base" nogil:
cdef cppclass openmode:
pass
cdef open_mode binary
cdef extern from "<iterator>" namespace "std" nogil:
cdef cppclass ostream_iterator[T,charT,traits](iterator[output_iterator_tag, void, void, void, void]):
basic_ostream[charT,traits]* out_stream
ctypedef charT char_type
ctypedef traits traits_type
ctypedef basic_ostream[charT,traits] ostream_type
ostream_iterator (ostream_type& )
ostream_iterator (ostream_type& , const charT* )
cdef class Matrix:
def __cinit__(self, int rows=0, int columns=0):
self._rows=rows
self._columns=columns
self.matrix=new vector[double]()
self.matrix.resize(rows*columns)
def __dealloc__(self):
del self.matrix
@cython.boundscheck(False)
@cython.wraparound(False)
cpdef double getVal(self, int r, int c):
return self.matrix[0][r*self._columns+c]
@cython.boundscheck(False)
@cython.wraparound(False)
cpdef void setVal(self, int r, int c, double v):
self.matrix[0][r*self._columns+c] = v
@cython.boundscheck(False)
@cython.wraparound(False)
cpdef void _write(self, char *filename):
cdef ofstream* outputter
outputter = new ofstream(filename, binary)
cdef int j
cdef ostream_iterator[double] os(outputter," ")
cdef ostream_iterator[double] oi(outputter,"\n")
for j from 0 <= j < self._rows:
copy(self.matrix.begin()+ j*self._columns,self.matrix.begin()+ (j+1)*self._columns,os)
copy(self.matrix.begin(),self.matrix.begin(),oi)
矩阵.pxd
from libcpp.vector cimport vector
cdef class Matrix:
cdef vector[double] *matrix
cdef int _rows
cdef int _columns
cpdef double getVal(self, int r, int c)
cpdef void setVal(self, int r, int c, double v)
cpdef void _write(self, char *filename)
错误信息是:
cdef ofstream out1(filename)
cdef int j
cdef ostream_iterator[double] os(out1," ")
^
------------------------------------------------------------
matrix.pyx:: Expected an identifier, found 'BEGIN_STRING'
Error compiling Cython file:
------------------------------------------------------------
...
cdef ofstream out1(filename)
cdef int j
cdef ostream_iterator[double] os(out1," ")
^
------------------------------------------------------------
matrix.pyx:: Expected ')', found 'CHARS'
任何使此代码工作的建议将不胜感激。
更新:
根据@DavidW 的回答,我编写了以下函数以将文件读入 matrix
对象。
from libcpp.string cimport string
cdef extern from "<sstream>" namespace "std" nogil:
cdef cppclass istringstream(istream):
istringstream() except +
istringstream(const string&) except +
void str(const string&)
cdef class Matrix:
def __cinit__(self, size_t rows=0, size_t columns=0):
self._rows=rows
self._columns=columns
self.matrix=new vector[double]()
self.matrix.resize(rows*columns)
cpdef void _read(self, str filename):
cdef ifstream* infile = new ifstream(filename)
cdef string line
cdef size_t i = 0
cdef size_t columns = 0
while (getline(infile[0], line, '\n')):
istringstream iss(line)
self.matrix.insert(self.matrix.begin()+i*columns,istream_iterator[double](line),istream_iterator[double]())
if (i==0):
columns= self.matrix.size()
del infile
return
最佳答案
我认为您的主要问题是 ofstream
和 ostream_iterator
既不能默认构造(构造时不带参数)也不能赋值,因此您不能使用它们在 Cython 中分配堆栈(即您需要使用 new
分配它们)。
我构建了一个非常简单的示例来展示如何执行此操作。我试图通过忽略不必要的模板参数(默认值是正确的)并仅包括您实际使用的函数来尽可能地简化 C++ 声明。
我已经将 ofstream
分配为带有 new
的指针,将 ostream_iterator
分配为临时值,我直接将其传递给 copy
。也可以将 ostream_iterator
分配为指针,尽管这似乎没有必要。
#distutils: language=c++
from libcpp.vector cimport vector
cdef extern from "<ostream>" namespace "std":
cdef cppclass ostream:
ostream& put(char c) # just to write the newlines
cdef extern from "<istream>" namespace "sts":
cdef cppclass istream:
pass
cdef extern from "<fstream>" namespace "std":
cdef cppclass ofstream(ostream):
ofstream(const char*)
cdef cppclass ifstream(istream):
ifstream(const char*)
cdef extern from "<iterator>" namespace "std":
cdef cppclass ostream_iterator[T]:
ostream_iterator(ostream&, const char*)
cdef cppclass istream_iterator[T]:
istream_iterator(istream&)
istream_iterator()
cdef extern from "<algorithm>" namespace "std":
OutputIterator copy[InputIterator,OutputIterator](InputIterator, InputIterator, OutputIterator)
def test_func_write(l):
"Takes a list/tuple, converts it to a vector
and then prints that twice"
cdef vector[int] v = l
cdef ofstream* fout = new ofstream("output.txt");
try:
copy(v.begin(),v.end(),ostream_iterator[int](fout[0]," "))
fout.put("\n")
copy(v.begin(),v.end(),ostream_iterator[int](fout[0]," "))
fout.put("\n")
finally:
del fout
def test_func_read():
cdef vector[int] v
cdef ifstream* fin = new ifstream("output.txt")
try:
v.insert(v.end(),istream_iterator[int](fin[0]),istream_iterator[int]())
return v
finally:
del fin
我正在使用 put
函数将换行符直接写入 fout
。
阅读总是比写作复杂一点。我们可以将 insert
直接插入到 vector 中,它会一直读取直到到达末尾。不幸的是,它对换行符和空格的处理方式相同(这在 C++ 流中很难更改),因此我们很难计算出矩阵形状。最简单的解决方案是编写文件,使第一个元素给出列数。更复杂的方法是使用 getline
将每一行作为一个字符串,然后为每一行制作一个 istringstream
。
对于 ostream_iterator
,控制格式并不真正起作用。 ostream
有多种函数来控制格式(例如 width
、fill
和 setf
。但是,它们只适用于下一个输出然后被重置。因此它们对于迭代器写入多个输出非常无用。一个常见的解决方案(12)似乎是编写一个包装类以应用于每个元素的格式化程序但这在 Cython 中并不实用。
以防万一你想使用格式标志(并一次写入一个元素)你会这样做
cdef extern from "<ostream>" namespace "std":
cdef cppclass fmtflags "std::ios_base::fmtflags":
pass
fmtflags left "std::ios_base::left"
fmtflags right "std::ios_base::left"
# etc...
cdef cppclass ostream:
#...
fmtflags setf(fmtflags)
int width(int)
char fill(char)
然后你只需调用:
fout.width(10)
fout.fill("x")
fout.setf(left)
就其值(value)而言,我真的不认为尝试在 Cython 中使用 C++ 标准库编写矩阵类是个好主意 - 你总是会与 Cython 对 C++ 模板的有限支持作斗争。
希望最终编辑:您使用 getline
和 istringstream
的“阅读”示例离我们不远了。只是为了列出我必须做出的改变
# istream needs a "bool" operator for you to use it in a while loop.
# You could also use the function "good()"
from libcpp cimport bool
cdef extern from "<istream>" namespace "std":
cdef cppclass istream:
bool operator bool()
# You need to declare getline. I'm using the simpler version without
# the delimiter but it doesn't really matter
cdef extern from "<string>" namespace "std":
istream& getline(istream&, string& s)
# the loop looks like:
while (getline(infile[0], line)):
self.matrix.insert(self.matrix.end(), # use "end" to insert at the back (this was a mistake in my original example
istream_iterator[double](istringstream(line)), # just make the istringstream as a temporary
istream_iterator[double]())
if (i==0):
columns= self.matrix.size()
i += 1 # you forgot this
关于c++ - 使用 ofstream 在 cython 中写下二维 vector ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48095958/
我想在一个函数中打开一个文件,将打开的文件对象返回给 main,并在另一个函数中使用它函数来填充文件。编译器似乎告诉我,我正在尝试访问 iostream 的私有(private)成员。有没有办法做到这
我最近写了一个记录器类。编译这段代码时: std::ofstream *stream = new std::ofstream; stream->open( log_file_name.c_str()
我有以下测试代码,其中有一个参数 fS,它是 ofstream 的容器: #include #include #include #include int
我正在尝试实现一个记录器,它可以注册到多个流,如 ostringstream、ofstream 等。我试图实现这样的功能 void register_stream(std::ostream& a);
我有一个在线程上写入文件的类 class A{ public: void writeToFile(ofstream& outFile, obj &a) { //...
我有以下代码 void _log_message(const char* fmt, ...) { va_list arg; ofstream logfile; cout << "Open Lo
我刚刚开始阅读如何打开和编辑文件。使用 ifstream 时,如果文件不存在,则不会创建它。 引用下面的代码,条件 (!outfile) 何时为假,就好像文件不存在一样,构造函数将简单地创建它,因此总
#include #define LOGFATAL(msg) log(0, msg) std::ofstream *logst = NULL; void log(int sev, char *msg
我在使用 ofstream 时遇到问题一次将两个不同的输出写入两个不同的文件。程序编译运行正常,并向p1output.txt写入数据,但是当我打开p2output.txt时,除了第一行内容外是空白的:
我有一个“资源模块”类来管理我的应用程序的所有资源,它主要从一个包含所有内容的文件“RESOURCES.DAT”中读取。 从文件中请求新数据的所有对象都通过 ResourceModule,因此我可以管
我遇到流问题,程序无法打开我要写入的文件。最小完整可变代码如下: #include #include using namespace std; int main(){ string roo
我已经研究了好几个小时了,我只知道答案很简单。似乎无论我做什么我都无法打开文件。这是一个多类程序,所以在标题中我有 #include #include class A{ string path
所以我想写一个可以像这样使用的缩进输出类: Debug f; f.open("test.txt"); f }' and '') ofs #include using namespace std;
大家好... 抱歉我的英语不好,但是会说西类牙语... 这周,为了这个proyect的学习和工作,我想创建一个软件来制作文件(.us)... 示例 char name[50]; //Or string
我不想在 main() 中构造 ofstream。这是我所做的,但它没有编译: #include using namespace std; class test { private: ofs
谁能告诉我这是怎么回事? #include #include #include #include #include class writeManager { std::vector
我有一个 C++ 类,它将其数据写出到二进制 std::ofstream。该类将数据存储为 boost:shared_array 但我已经消除了这个问题。问题出在 ofstream 上对 write(
在我的程序中,我的 dataout: void outfile 没有写入文件,任何人都可以找出原因吗? using namespace std; #include #include #include
我想在文件上写点东西。但它只是没有像它必须假设的那样编写。 void main() { int accno; char name[20]; float deposit;
我遇到了一个奇怪的问题。我有两个函数,它们都有一个通过引用传递的 ofstream。但是,当我调用第二个函数时,正在打印第一个函数的一部分。 这是第一个函数: void GamePlay::dealD
我是一名优秀的程序员,十分优秀!