我想读取包含数据库表(TPCH)的CSV文件。每个文件都有不同数量的列,行和数据类型。
例如:
file1: Int, double, char[]
file2: double, char[], int, int
另一个要求是每列应该驻留在一个数组中(对于每一列,一个数组 - 不是每行)。
我的解决方案: 目前我在运行时使用new创建数组,具体取决于数据类型和csv文件的大小
e.g. file1: would be int[] , double[]...
然后我将数组的起始地址存储为map *中的void *(int,void *)。
当我想从数组中读取值时,我必须检索void *并根据类型进行转换。
正如你所看到的,我有很多指针和铸造,这是顽皮的。是否有更好的方法以Columnar格式存储表?我想使用数组,因为我经常复制它们并通过网络传输它们。另外,我不想使用升级库。
答案 0 :(得分:0)
是的,指针往往导致头痛的头脑。首先,我建议你使用STL容器,例如std::vector
,它会让你的生活更轻松。不需要提升,甚至不需要新的C ++编译器,因为std::vector
很长一段时间都在这里。
但我不明白为什么要存储数组的起始地址。无论如何,如果您只想存储地址,可以使用标题文件<cstdint>
并使用类型intptr_t / uintptr_t
,以保证能够保存void*
。
答案 1 :(得分:0)
这是variant
的一个很好的用例。在C ++ 17中,我们将此作为标准库的一部分,但是现在我们仍然使用boost
实现。
如果您不想使用boost
,可以选择几种方式,但它们至少有点粗略。
void*
。出于多种原因,这是不可取的。你知道我已经在这里钻研了。union
。在处理具有构造函数和析构函数的对象时,这也是不可取的。你必须记住调用析构函数,你必须知道调用构造函数到位。优于void*
,但只是勉强。假设你正在处理所有原始类型,std::vector<some_union_type>
可能不会那么糟糕,但是一旦你引入动态大小的字符串,你就会陷入伤害的世界。char[]
(更具体地说,std::vector<char>
)中,并在某种枚举中保留有关数据类型的元数据。使用该枚举将字节转换为正确的类型。这是一个非常多毛的解决方案,可以手工拼凑,但它与variant
通常的实现类似。std::unique_ptr
中)并通过执行dynamic_cast
将它们取出,直到获得正确的类型(或将数据类型存储在枚举中并根据该类型进行转换)。这可能是最高级别的#34;解决方案,并且可能比前三个解决方案更容易实现。any
的特例(在另一个答案中提到)。 Sean Parent涵盖here。对于您的情况,您可能会发现自己实现类似variant::visitor
模式的内容以获取所需的数据。或许使用boost::variant
看起来并不那么糟糕。 ;)