2017-02-15 44 views
3

我正在讀取和寫入csv的數據。在C++中用字符串::擦除提取數據

所以我想出了這個問題。

我正在從csv開始,getline(myfile, myline);,我發送myline到一個函數,以便提取所有無用的信息,並保持某些我需要的特定','(逗號)之間的部分。

我實現了這個使用此項功能:

int get_id(string myline) { 
    int id; 
    size_t pos; 
    pos = myline.find(","); 
    myline.erase((myline.begin() + pos), myline.end()); 
    stringstream converter(myline); 
    converter >> id; 
    return id; 
} 

我只有一個myline.find(",");,因爲我想要的數據是第一線的。我的csv格式的

例子:

id,name,age,address 

所以我具有myline.erase()我想是因爲當我把它在評論它運行平穩錯誤。我想知道這是否正確,我添加了一個size_tmyline.begin()? (沒有編譯錯誤)。作爲提取數據的心態,這也是正確的嗎?

的錯誤是:

終止叫做拋出的一個實例後 '的std :: length_error' 什麼():basic_string的:: _ S_create

回答

1

該示例與提供的數據不會導致錯誤。如果輸入不包含逗號,則會出現問題,例如,如果嘗試標記最後一個元素,則會遇到問題。 std::string::find返回npos如果找不到匹配項。 npos的值是std::size_t的最大值(如果您使用默認分配器)。將此值添加到begin會給你一個無效的迭代器。

在擦除之前只需比較npos即可避免此問題。

if (pos != string::npos) { 
    myline.erase((myline.begin() + pos), myline.end()); 
} 
+0

是的,這聽起來很合理,因爲我在一個大循環中調用這個函數。但我想知道如何,因爲我檢查了eof。 –

1

很難明白你爲什麼看到問題。我的建議:

刪除erase函數調用。如果該行包含一個數字後跟一個,,則流提取器將以任何方式停止在,。只需使用:

int get_id(string myline) { 
    int id = 0; 
    stringstream converter(myline); 
    converter >> id; 
    return id; 
} 

如果您必須清除,您可能需要添加其他檢查。

int get_id(string myline) { 

    // Erase only if there is a "," in the line. 
    atuo pos = myline.find(","); 
    if (pos != std::string::npos) 
    { 
     myline.erase((myline.begin() + pos), myline.end()); 
    } 

    int id = 0; 
    stringstream converter(myline); 
    converter >> id; 
    return id; 
} 
+0

嗯..是的,檢查'pos'絕對可以救我。問題的負面是如果pos變爲-1意味着這個字符串甚至不應該在那裏。 –

+0

@Theo.Fanis,你將不得不提出一個處理這個問題的策略。至少這可以確保當你不應該調用'erase'時。 –

+0

是的,我知道,現在這個問題解決了,我會回到我的主要。非常感謝你 ! –