2015-10-13 78 views
1

我有以下的功能,即寫入vector到CSV文件:刪除尾隨逗號使用複製和ostream_iterator矢量書面

#include <math.h> 
#include <vector> 
#include <string> 
#include <fstream> 
#include <iostream> 
#include <iterator> 
using namespace std; 

bool save_vector(vector<double>* pdata, size_t length, 
       const string& file_path) 
{ 
    ofstream os(file_path.c_str(), ios::binary | ios::out); 
    if (!os.is_open()) 
    { 
     cout << "Failure!" << endl; 
     return false; 
    } 
    os.precision(11); 
    copy(pdata->begin(), pdata->end(), ostream_iterator<double>(os, ",")); 
    os.close(); 
    return true; 
} 

然而,CSV文件的結尾是這樣的:

1.2000414752e-08,1.1040914566e-08,1.0158131779e-08,9.3459324063e-09, 

也就是說,一個尾隨逗號被寫入文件。當我嘗試使用其他軟件程序加載文件時,這會導致錯誤。

什麼是最簡單,最有效的方法來擺脫(理想情況下,永遠不會寫)這個尾隨逗號?

+0

您的問題將很快得到解決:http://en.cppreference.com/w/cpp/experimental/ostream_joiner – vsoftco

回答

3

正如您所觀察到的,通過std::copy進行復制並不能解決問題,只會輸出一個,。有一個提案可能會在未來的C++ 17標準中做到:ostream_joiner,這將完全符合您的期望。

但是,現在可用的快速解決方案是手動完成。

for(auto it = std::begin(*pdata); it != std::end(*pdata); ++it) 
{ 
    if (it != std::begin(*pdata)) 
     std::cout << ","; 
    std::cout << *it; 
} 
+0

我現在正在使用'-std = C++ 11'作爲編譯器選項。它看起來不會爲我工作(關於獲得'實驗')。我應該使用什麼?或者也許我需要安裝'實驗性的'? – dbliss

+0

它似乎還沒有包含在gcc中,我無法用gcc5.2編譯。 – vsoftco

+0

我一直在使用'C++'版本4.8.4和'g ++'版本4.8.4(可能會也可能不是同一件事),但沒有運氣。 – dbliss

0

我是忽略處理的第一要素特種印刷的逗號:

if (!pdata->empty()) { 
    os << pdata->front(); 
    std::for_each(std::next(pdata->begin()), pdata->end(), 
        [&os](auto&& v){ os << ", " << v; }); 
} 

顯然,這個代碼進入打印打印範圍適配器的功能。

+0

我不明白究竟是如何工作的。你不應該去'end() - 1'元素嗎?但是如果你把最後一個元素看作是特殊的,那麼你會遇到一些問題。 'std :: forward_list',它只有ForwardIterable。 – vsoftco

+0

@vsoftco:是的,有一個-1失蹤。 ...是的,它不適用於'std :: forward_list',這不是問題所在(使用'-1'實際上也不能用於'std :: list',但可以使用'std :: prev()')修復。 –