在C++中编译时从CSV创建矢量

Create vector from CSV at compile time in C++

本文关键字:CSV 创建 C++ 编译      更新时间:2023-10-16

我正试图为Xilinx Zynq SoC(ARM Cortex)创建一个查找表。

我有一个CSV文件,其中包含1330个条目,我在运行时无法读取或解析这些条目。我最近能做到的是在编译时。我读到可以将文件嵌入到可执行文件中,以便在运行时使用。

换句话说,我希望在运行时读取和解析CSV文件,而原始文件实际上不在任何文件系统上,因为它是一个嵌入式设备。所以我需要以某种方式将CSV文件嵌入到可执行文件中。我该如何实现这样的目标?

CSV文件如下所示(此处为完整文件);

0,0,48,112,160,208,272,320,368,....,65440,65488

您要求vector,但我不确定您为什么一定要它。数据将不可避免地占用应用程序只读(".text"或".rodata"或类似的部分)中的空间,尽管您可以在必要时将其转换为vector(这将占用堆空间,并需要从只读.text/.rodata部分中的数据进行运行时构造和初始化),您还可以将其用作POD数组,因为我怀疑您是否会在运行时更改数据。所以,要创建一个数据的constPOD数组,您可以这样做。。。。

const int myArray[] =
{
#include "myCsvFile.csv"
};

如果元素的数量不是固定的,您的程序可以使用sizeof(myArray)/sizeof(myArray[0])来确定数量。即使它是一个固定的大小,这种技术可能是最好的。当然,如果您的所有条目都是无符号的,并且可以容纳在16位以内(粗略检查建议是这样),那么您可以将其定义为unsigned shortuint16_t的数组,而不是将其定义成int的数组,以节省空间。

我还应该提到,const关键字在这里很重要:如果没有它,您的数组将占用两倍的内存:首先,它将占用只读部分(.text或.rodata或其他)中的空间,在应用程序初始化期间,运行时将在读/写数据部分(可能是.data)中创建只读数据的读/写副本,其中分配了myArray。为了避免这种情况,将其定义为const,然后myArray的地址将在只读部分,并且不会复制到读/写数据部分。

由于数据是无符号整数的普通数组,因此可以使用预编译器

假设csv文件在data.csv文件中。

然后只需在.cpp文件中,您就可以执行以下操作:

const unsigned int k_Data[] = {
#include "data.csv" // << Preprocessor will replace this line with the contents of data.csv
};
#include <iostream>
int main()
{
std::cout << k_Data[3];
}

112

对于您拥有的特定类型的CSV数据,例如

0,0,48,112,160,208,272,320,368,432,480,512,576,640,704,752,800,848,896,......

它基本上只是一堆数字,您应该能够使用实际的#include语句来包括它们,所以;

const unsigned short myCSV[] ={
#include "./theCSV.data"
};

我使用unsigned short,因为最大的数字看起来像64k,这会节省一些空间——但如果你认为这个数字可能大于64k ,你可能想使用int