让我说我在一些文件中存储标题,但标题的某些部分是动态长度,如下所示:
struct HeaderTest {
int someparam;
int more;
int arrsize; // how big array, read arrsize elements into arr:
int arr[arrsize]; // not valid
};
是否有一些优雅的方法可以将动态数据读入结构体?
答案 0 :(得分:6)
您可以在结构中定义结构,而不是在结构中包含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;
}
否则,请使用第一个结构!
在任何地方阅读你的评论,我觉得我应该建议你拿一本好书,先学习它。以下是真正的好书的列表:
答案 1 :(得分:2)
好吧,如果您不想使用容器类(不确定为什么不这样做),您可以将arr声明为指向int的指针,并将其保留给客户端以初始化指向有效内存位置的指针以及正确初始化arrsize。
那就是说,你应该使用一个向量。为什么让事情变得比他们需要的更难?
答案 2 :(得分:1)
这个答案比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);
答案 3 :(得分:0)
我认为没有一种非常优雅的方式。你应该把这个动态成员作为一个指针,然后先读取所有其他成员,为最后一个成员分配内存,然后读取其余的数据。
由于您使用的是C ++,因此您可以很好地将其封装在一个类中,这样您就不必再担心代码中的这些细节了。另外,正如其他人所说的那样,std::vector
比简单的指针和手动分配的内存更像C ++。它也会更耐内存泄漏。
答案 4 :(得分:0)
没有人能够为您提供您想要的解决方案,但我已经为您设计了解决方案。 此函数采用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;
}