2016-03-15 88 views
0

我想讀取包含數據庫表(TPCH)的CSV文件。每個文件具有不同數量的列,行和數據類型。C++使用不同數據類型在列式存儲中讀取CSV表

例如:

file1: Int, double, char[] 
file2: double, char[], int, int 

一個進一步的要求是每列應駐留在一個陣列(對於每一列的陣列 - 不每行)。

我的解決方案:與新視數據類型和CSV文件的

e.g. file1: would be int[] , double[]... 

然後我存儲我的數組作爲起始地址的大小運行目前我創建數組一個void *在地圖上(int,void *)。

當我想從數組中讀取值時,我必須檢索void *並根據類型進行投射。

正如你可以看到我有很多指針和鑄造哪些是調皮的。有沒有更好的方法來存儲一個表在列表格式?我想使用數組,因爲我經常複製它們並通過網絡傳輸它們。另外,我不想使用boost庫。

回答

0

是的,指針往往導致montains的頭痛。首先,我建議你使用STL容器,比如std::vector,它會讓你的生活更輕鬆。不需要提升,甚至不需要新的C++編譯器,因爲std::vector已經很長時間了。

但我不明白你爲什麼要存儲你的數組的起始地址。無論如何,如果你只是想存儲一個地址,你可以使用頭文件<cstdint>並使用類型intptr_t/uintptr_t,保證能夠保存void*

+0

非常感謝你。與矢量點是我需要一個地圖,我可以存儲矢量,但他們有不同的類型,如矢量(int)或矢量(雙)。是否有可能將這些不同的矢量類型存儲在一張地圖中? 如果我聽錯了,只是糾正我,但我需要存儲的起始地址,因爲我的數組是動態分配的,並駐留在堆。 – Goaty

+0

有'的boost :: any'或'的boost :: variant',但如果你不能使用它們,我們需要考慮的另一種方法。 – informaticienzero

0

這是variant的一個很好的用例。在C++ 17中,我們將把它作爲標準庫的一部分,但現在我們堅持使用boost實現。

如果你不想使用boost有幾種選擇,但它們都至少有點毛病。

  1. void*。由於多種原因,這是不可取的。你知道,所以我不會在這裏深究。
  2. union。處理具有構造函數和析構函數的對象時,這也不是理想的。你必須記得調用析構函數,你必須知道調用構造函數。好於void*,但只是勉強。假設你正在處理所有的原始類型,std::vector<some_union_type>可能不會那麼糟糕,但是一旦你引入動態大小的字符串,你就處於一個受到傷害的世界。
  3. 字節操縱。將所有內容存儲在char[](更具體地說,是std::vector<char>),並在某種枚舉中保留有關數據類型的元數據。使用該枚舉將字節轉換爲正確的類型。這是一個手工放在一起的非常多毛的解決方案,但它類似於variant通常如何實現。
  4. 運行時多態性。創建一個父類,然後爲每個數據類型創建一個子類。動態分配的子類(它們存儲在一個std::unique_ptr),直到你得到正確的類型讓他們出去做dynamic_cast(或數據類型存儲在一個枚舉和CAST基於這一點)。這可能是最「高級」的解決方案,可能比前三種解決方案更容易獲得。
  5. 基於概念的多態性。這基本上是滾動any(在另一個答案中提到)的特例。肖恩家長覆蓋它here。對於你的情況,你可能會發現自己實現像variant::visitor模式的東西拿到你想要的數據。

也許使用boost::variant畢竟看起來不那麼糟糕。 ;)

相關問題