比方说,我在一些文件中存储标题,但标题的一部分是dynamic长度,就像这样看起来:
struct HeaderTest { int someparam; int more; int arrsize; // how big array, read arrsize elements into arr: int arr[arrsize]; // not valid };
有没有一些优雅的方式来读取dynamic数据到一个结构?
你的结构中没有arr
和arrsize
变量,你可以像这样定义你的结构:
struct HeaderTest { int someparam; int more; std::vector<int> data; }
没有arr,没有arrsize。 只需使用std::vector
和std::vector::size()
。 这是优雅的!
如果你想从文件中读取二进制数据,那么你可以这样写:
struct HeaderTest { int someparam; int more; int size; char *data; }
否则,去第一个结构!
读到你的评论,我觉得我应该建议你找一本好书,先研究一下。 这里是真正好书的列表:
最终的C ++图书指南和列表
那么,如果你不想使用一个容器类(不知道你为什么不这样做),你可以声明arr作为指向int的指针,并将其留给客户端来初始化指向有效内存位置的指针初始化arrsize。
这就是说,你应该只使用一个矢量。 为什么让事情比他们需要的更困难?
这个答案比C ++更适用于C语言,但是,您可以轻松地使用realloc()来调整缓冲区的大小,使其尽可能大。 如这个伪代码所示。
struct HeaderTest { int someparam; int more; int arrsize; int arr[]; }; HeaderTest* pkt = (HeaderTest*)malloc(sizeof(HeaderTest)); read(&pkt,sizeof(pkt)); pkt = (HeaderTest*)realloc(pkt,sizeof(HeaderTest)+sizeof(pkt->arr[0])*pkt->arrsize); read(pkt->arr,sizeof(int)*pkt->arrsize);
我不认为有一个非常优雅的方式。 您可能应该使该动态成员为指针,然后先读取所有其他成员,为最后一个分配内存,然后读取其余的数据。
由于你使用的是C ++,所以你可以很好地把它封装在一个类中,这样你就不用担心代码中的细节了。 另外,正如其他人所说,一个std::vector
将是一个比简单的指针和手动分配的内存更类似于C ++的方法。 它也会更耐内存泄漏。
没有人能够给你想要的解决方案,但我已经为你设计了。 这个函数接受一个C字符串文件名,打开文件并为你读取内容。 它返回一个int *,可以分配给t.container。 请享用。
int* read(char* filename) { // open file ifstream f; f.open(filename, ios::binary); // get file size f.seekg (0, ios::end); int length = f.tellg(); f.seekg (0, ios::beg); // allocate new int* length = (length -(sizeof(int)*2)) / sizeof(int); int* buf = new int[length]; for(int i = 0; i < length; ++i) { // create byte array to hold bytes unsigned char* temp = new char[sizeof(int)]; stream.read((char*)temp, sizeof(int)); // convert byte array to int for(int j = 0; j < sizeof(int); ++j) { buf[i] = buf[i] + (temp[j] << (j*8)); } delete[] temp; } f.close(); return buf; }