2017-02-15 12 views
3

私はcsvのデータの読み書きに取り組んでいます。C++でstring :: eraseを使ってデータを抽出する

私はこの問題を思いつきました。

私はgetline(myfile, myline);でcsvの行を取っています。すべての無駄な情報を抽出し、必要な特定の '、'(カンマ)の間に部分を保持するために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

hmm ..ええ、「pos」を確認すると確実に私を救うことができます。問題のネガティブは、posが-1になると、この文字列はそこに存在すべきではないということです。 –

+0

@ Theo.Fanis、あなたはその問題に対処するための戦略を考え出す必要があります。少なくともこれは、あなたがしてはいけないときに 'erase'を呼び出さないようにします。 –

+0

はい、私はこの問題が解決したので、私は私のメインに戻るだろう知っています。どうもありがとうございました ! –

関連する問題