如何在C++中将数据嵌入数组中?

发布于 2025-01-25 03:13:12 字数 375 浏览 4 评论 0原文

我想在编译时间将数据库加载到数组中:

//a.dat
1 2 3 4 5
int main(){ 
    unsigned int a[5]=f("a.dat");
}

但是我找不到stackoverflow中的简单解决方案。有没有人可以给予办法做到这一点。我想有两种方法:

  1. 使用程序以硬码样式制作数据库,代码:
a[]={1,2,3,4,5};
  1. 使用函数读取数据(但在运行时),例如:
a[5]=f("a.dat");

I want to load a database into an array at compile time like:

//a.dat
1 2 3 4 5
int main(){ 
    unsigned int a[5]=f("a.dat");
}

But I can't find a simple solution in StackOverflow. Is there anyone can give a way to make it. I guess there are two ways:

  1. Use a program to make the database in hard-code style, code:
a[]={1,2,3,4,5};
  1. use a function to read the data (but that is at runtime), like:
a[5]=f("a.dat");

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我们只是彼此的过ke 2025-02-01 03:13:12

第三个,但也不理想的选择是#include您的数据文件。

该解决方案要求您调整数据以在值之间包括一个逗号:

a1.dat:

1, 2, 3, 4, 5

cpp1:

#include <iostream>

int main()
{
    constexpr int N = 5;
    unsigned int a[N] = {
        #include "a1.dat"
    };

    for (size_t i=0; i<N; ++i)
    {
        std::cout << a[i] << " ";
    }
    std::cout << "\n";
}

但是,当然,n(值数)和该值的分离和该值的实际值数字不是好的设计 - n需要更新,以防A.DAT更改中的值数量,可以很容易地忘记。

因此,您可能需要选择将整个数组声明移至标题:

A2.DAT:

    unsigned int a[] = {
        1, 2, 3, 4, 5
    };

CPP2:

#include <iostream>

int main()
{
    constexpr int N = 5;
    #include "a2.dat"
    for (size_t i=0; i<N; ++i)
    {
        std::cout << a[i] << " ";
    }
    std::cout << "\n";
}

尽管这不会改变问题,而必须指定某处指定元素的数量(并注意省略na的声明中,意味着现在编译器无法执行n a中的元素实际上存在n元素)

为了解决这个问题,您可能需要使用std :: vector而不是:

a3.dat:

    std::vector<unsigned int> a = {
        1, 2, 3, 4, 5
    };

cpp3:

#include <iostream>
#include <vector>

int main()
{
    #include "a3.dat"
    for (auto anum: a)
    {
        std::cout << anum << " ";
    }
    std::cout << "\n";
}

std :: embed inde 上面提到的提案也对此“解决方案”也有一些评论。

当然,#include期望数据的格式为源代码,
因此,该程序在壮观的词法错误中失败

A third, but also not ideal option would be to #include your data file.

This solution requires you to adapt your data to include a comma between the values though:

a1.dat:

1, 2, 3, 4, 5

cpp1:

#include <iostream>

int main()
{
    constexpr int N = 5;
    unsigned int a[N] = {
        #include "a1.dat"
    };

    for (size_t i=0; i<N; ++i)
    {
        std::cout << a[i] << " ";
    }
    std::cout << "\n";
}

But of course, the separation between N (the number of values) and the actual values for the numbers is not good design - N needs to be updated in case the number of values in a.dat changes, which could easily be forgotten.

You might therefore want to choose to move the whole array declaration to the header:

a2.dat:

    unsigned int a[] = {
        1, 2, 3, 4, 5
    };

cpp2:

#include <iostream>

int main()
{
    constexpr int N = 5;
    #include "a2.dat"
    for (size_t i=0; i<N; ++i)
    {
        std::cout << a[i] << " ";
    }
    std::cout << "\n";
}

Though this doesn't change the problem with having to specify the number of elements somewhere (and note that leaving out the N in the declaration of a means that now there is no way for the compiler to enforce that there are actually N elements in a)!

To circumvent this, you might want to use an std::vector instead:

a3.dat:

    std::vector<unsigned int> a = {
        1, 2, 3, 4, 5
    };

cpp3:

#include <iostream>
#include <vector>

int main()
{
    #include "a3.dat"
    for (auto anum: a)
    {
        std::cout << anum << " ";
    }
    std::cout << "\n";
}

The std::embed proposal mentioned above also has some comments on this "solution":

Of course, #include expects the format of the data to be source code,
and thusly the program fails with spectacular lexer errors

云胡 2025-02-01 03:13:12

使用具有“ C风格”输出的XXD,以转换您的输入以进行合适的“嵌入”:

$ xxd -i a.bin
unsigned char a_bin[] = {
  0xd0, 0xe5, 0x46, 0x82, 0x0d, 0xda, 0x72, 0xe8, 0x0f, 0x3f, 0x00, 0x66,
  0xf0, 0xdd, 0x67, 0xd5
};
unsigned int a_bin_len = 16;

变量名称基于输入文件名,因此请明智地命名源文件。

如果您有“构建管道”,这将变得方便,这可能与makefile一样最小:

a.c: a.bin
    xxd -i 
lt; $@

main: main.o a.o
    $(CC) -o $@ $^

不要忘记将生成的ac添加到.gitignore或类似的东西。

Use xxd that has a "C-style" output, to convert your input for suitable "embedding":

$ xxd -i a.bin
unsigned char a_bin[] = {
  0xd0, 0xe5, 0x46, 0x82, 0x0d, 0xda, 0x72, 0xe8, 0x0f, 0x3f, 0x00, 0x66,
  0xf0, 0xdd, 0x67, 0xd5
};
unsigned int a_bin_len = 16;

The variable names are based on input filename, so name your source files wisely.

This is getting convenient if you have a "build pipeline", which can be as minimal as a Makefile:

a.c: a.bin
    xxd -i 
lt; $@

main: main.o a.o
    $(CC) -o $@ $^

Don't forget to add the generated a.c into your .gitignore or something alike.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文