C++ 将文件内容加载到C++;结构
我有一个ASCII文件,看起来像这样(文件很大,所以只粘贴部分内容): 我有一个结构,看起来像这样:C++ 将文件内容加载到C++;结构,c++,struct,file-io,C++,Struct,File Io,我有一个ASCII文件,看起来像这样(文件很大,所以只粘贴部分内容): 我有一个结构,看起来像这样: typedef struct frame { uint16_t kps; uint16_t num_h_region; uint16_t num_v_region; uint16_t num_r; uint8_t reserved1[7]; uint8_t kp_per_region[100]; uint8_t reserved[397]; kp_info_t
typedef struct frame {
uint16_t kps;
uint16_t num_h_region;
uint16_t num_v_region;
uint16_t num_r;
uint8_t reserved1[7];
uint8_t kp_per_region[100];
uint8_t reserved[397];
kp_info_t kp_info[2000];
uint32_t desc[2000];
} frame_t;
frame_t fr;
fr.kps = 0x000c;
fr.num_h = 0x000a;
fr.num_v = 0x000a;
fr.num_r = 0x0064;
fr.reserved1[0] = 0xff;
fr.reserved1[1] = 0xff;
fr.reserved1[2] = 0xff;
fr.reserved1[3] = 0xff;
fr.reserved1[4] = 0xff;
fr.reserved1[5] = 0xff;
fr.reserved1[6] = 0xff;
fr.reserved1[7] = 0xff;
fr.kps_per_region[0] = 0x03;
fr.kps_per_region[1] = 0x05;
fr.kps_per_region[2] = 0x0a;
fr.kps_per_region[3] = 0x1f;
fr.kps_per_region[4] = 0x11;
fr.kps_per_region[5] = 0x00;
fr.kps_per_region[6] = 0x00;
fr.kps_per_region[7] = 0x0b;
fr.kps_per_region[8] = 0x00;
fr.kps_per_region[9] = 0x00;
fr.kps_per_region[10] = 0x00;
fr.kps_per_region[11] = 0x00;
fr.kps_per_region[12] = 0x00;
fr.kps_per_region[13] = 0x00;
fr.kps_per_region[14] = 0x00;
fr.kps_per_region[15] = 0x02;
.. so on.
其中:
typedef struct kp_info {
uint32_t subpixel_idx_x;
uint32_t subpixel_idx_y;
uint32_t orientation;
uint32_t laplacian;
uint8_t scale;
uint8_t minima; // 1 bit
uint8_t dmy1[14];
uint32_t subpixel_match0_x;
uint32_t subpixel_match0_y;
uint32_t subpixel_match1_x;
uint32_t subpixel_match1_y;
uint32_t distance_match0;
uint32_t distance_match1;
uint8_t ambiguous; // 1 bit
uint8_t dmy2[7];
} kp_info_t;
输入文件应分配给框架结构成员,如下所示:
typedef struct frame {
uint16_t kps;
uint16_t num_h_region;
uint16_t num_v_region;
uint16_t num_r;
uint8_t reserved1[7];
uint8_t kp_per_region[100];
uint8_t reserved[397];
kp_info_t kp_info[2000];
uint32_t desc[2000];
} frame_t;
frame_t fr;
fr.kps = 0x000c;
fr.num_h = 0x000a;
fr.num_v = 0x000a;
fr.num_r = 0x0064;
fr.reserved1[0] = 0xff;
fr.reserved1[1] = 0xff;
fr.reserved1[2] = 0xff;
fr.reserved1[3] = 0xff;
fr.reserved1[4] = 0xff;
fr.reserved1[5] = 0xff;
fr.reserved1[6] = 0xff;
fr.reserved1[7] = 0xff;
fr.kps_per_region[0] = 0x03;
fr.kps_per_region[1] = 0x05;
fr.kps_per_region[2] = 0x0a;
fr.kps_per_region[3] = 0x1f;
fr.kps_per_region[4] = 0x11;
fr.kps_per_region[5] = 0x00;
fr.kps_per_region[6] = 0x00;
fr.kps_per_region[7] = 0x0b;
fr.kps_per_region[8] = 0x00;
fr.kps_per_region[9] = 0x00;
fr.kps_per_region[10] = 0x00;
fr.kps_per_region[11] = 0x00;
fr.kps_per_region[12] = 0x00;
fr.kps_per_region[13] = 0x00;
fr.kps_per_region[14] = 0x00;
fr.kps_per_region[15] = 0x02;
.. so on.
我已经将ASCII文件转换为二进制文件,但是我不知道如何正确地进行赋值。我正在努力解决排序问题,以及在(不同的)结构中使用结构数组的问题
以下是二进制文件的外观:
00000000: ffff ffff ffff ffff 0064 000a 000a 000c .........d......
00000010: 0200 0000 0000 0000 0b00 0011 1f0a 0503 ................
00000020: 0000 0000 0000 0200 0000 0000 0000 0000 ................
00000030: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000040: 0200 0000 0000 0000 0000 0204 0000 0000 ................
00000050: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000060: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000070: ffff ffff ffff ffff ffff ffff 0000 0000 ................
00000080: ffff ffff ffff ffff ffff ffff ffff ffff ................
00000090: ffff ffff ffff ffff ffff ffff ffff ffff ................
000000a0: ffff ffff ffff ffff ffff ffff ffff ffff ................
000000b0: ffff ffff ffff ffff ffff ffff ffff ffff ................
000000c0: ffff ffff ffff ffff ffff ffff ffff ffff ................
000000d0: ffff ffff ffff ffff ffff ffff ffff ffff ................
union u_frame {
char mem[sizeof(frame_t)];
frame_t fr;
} uf;
void load_text_file(frame_t& f, const std::string& s)
{
std::fstream input;
input.open(s, std::fstream::in | std::fstream::binary);
if(!input.is_open())
{
fprintf(stderr, "\nError opening file\n");
exit(1);
}
std::cout << "Size of frame_t = " << std::hex << sizeof(frame) << std::endl;
std::cout << "File opened successfully\n";
input.read(uf.mem, sizeof(frame_t));
std::cout << "total_kps = " << uf.fr.total_kps
<< "\nnum_h_region = " << uf.fr.num_h_region
<< "\nnum_v_region = " << uf.fr.num_v_region
<< "\nnum_region = " << uf.fr.num_region;
for(size_t i = 0; i < 8; ++i)
std::cout << "\nreserved[" << i << "] = " << std::hex << (std::uint32_t)(uf.fr.reserved1[i]);
// Printing the first 15 kp_per_region
for(size_t i = 0; i < 15; ++i)
{
std::cout << "\nkps_per_region[" << i << "] = " << (std::uint32_t)(uf.fr.kp_per_region[i]);
}
}
int main() {
frame_t left;
std::cout << "Loading left frame -- \n";
load_text_file(left, "line_ddr.bin");
return 0;
}
以下是我的尝试:
00000000: ffff ffff ffff ffff 0064 000a 000a 000c .........d......
00000010: 0200 0000 0000 0000 0b00 0011 1f0a 0503 ................
00000020: 0000 0000 0000 0200 0000 0000 0000 0000 ................
00000030: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000040: 0200 0000 0000 0000 0000 0204 0000 0000 ................
00000050: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000060: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000070: ffff ffff ffff ffff ffff ffff 0000 0000 ................
00000080: ffff ffff ffff ffff ffff ffff ffff ffff ................
00000090: ffff ffff ffff ffff ffff ffff ffff ffff ................
000000a0: ffff ffff ffff ffff ffff ffff ffff ffff ................
000000b0: ffff ffff ffff ffff ffff ffff ffff ffff ................
000000c0: ffff ffff ffff ffff ffff ffff ffff ffff ................
000000d0: ffff ffff ffff ffff ffff ffff ffff ffff ................
union u_frame {
char mem[sizeof(frame_t)];
frame_t fr;
} uf;
void load_text_file(frame_t& f, const std::string& s)
{
std::fstream input;
input.open(s, std::fstream::in | std::fstream::binary);
if(!input.is_open())
{
fprintf(stderr, "\nError opening file\n");
exit(1);
}
std::cout << "Size of frame_t = " << std::hex << sizeof(frame) << std::endl;
std::cout << "File opened successfully\n";
input.read(uf.mem, sizeof(frame_t));
std::cout << "total_kps = " << uf.fr.total_kps
<< "\nnum_h_region = " << uf.fr.num_h_region
<< "\nnum_v_region = " << uf.fr.num_v_region
<< "\nnum_region = " << uf.fr.num_region;
for(size_t i = 0; i < 8; ++i)
std::cout << "\nreserved[" << i << "] = " << std::hex << (std::uint32_t)(uf.fr.reserved1[i]);
// Printing the first 15 kp_per_region
for(size_t i = 0; i < 15; ++i)
{
std::cout << "\nkps_per_region[" << i << "] = " << (std::uint32_t)(uf.fr.kp_per_region[i]);
}
}
int main() {
frame_t left;
std::cout << "Loading left frame -- \n";
load_text_file(left, "line_ddr.bin");
return 0;
}
如果需要其他信息,请告诉我(特别是因为我只粘贴了输入文件的一部分)。您的代码完全按照您指定的方式执行。获取
输入
流并将sizeof(frame\t)
字节加载到uf
中。需要注意的一点是,您的文件/流是从“左到右”、“逐字节”读取的,因此前两个字节(因为您指定了uint16_t
)将从ffff ffff ffff 0064 000a 000a 000a 000c…
加载到帧中。kps
将是ffff
,而不是000c
。进一步研究的好方法是设置几个断点并逐步调试代码。您将学习重要的调试技术,并进一步了解代码的工作原理
另一方面,我很惊讶您没有得到
堆栈溢出异常。该结构非常庞大没有涉及太多细节,例如填充如何工作以及应用程序限制是什么-这些对于理解非常有用,但对于解决此类问题不是必需的,我很乐意支持不同的方法
我们需要解决两个主要问题:
我们正在序列化和反序列化数据
我们有一个大文件,其中存在这样的数据(或者我们想写它)
因此,我们应该问两个问题:
我们如何序列化和反序列化数据
这种序列化和反序列化数据的方法是否可以工作,即在文件上作为二进制流
作为对第一个问题的回答,我想到的第一个库现在需要回答第二个问题,事实上,文档中说这应该是可能的:这里有一个Kaitai结构模式,它处理文件的前32个字节,您可以在以下位置检查它:
不幸的是,我无法帮助您编写其余部分,因为我不清楚文件的其余部分如何映射到您显示的结构。“我已将ASCII文件转换为二进制文件,但我不知道如何正确进行赋值。”让我们看看失败的尝试。考虑使用一些类似的方法来生成把二进制文件解析成可以使用的字段的代码。这避免了繁琐的复制粘贴,并且可以跨语言移植。关于您所展示的代码,您描述为“像这样的成员”:您能否解释一下,仅仅按照原样获取该代码,您到底在“挣扎”什么,并用从文件读取的值替换硬编码常量?您正在从Big-endian中的最低内存地址读取,其中预期从Little-endian中的行上最远的内存地址读取@NullPointer(用于保留后)@NullPointer-我如何编辑代码才能做到这一点?