2016-08-03 5 views
0

私はファイル内に行を持ち、その行にある行はそれぞれスペースで区切られています。ここではラインのsimpliefied例です:文字列をスペースで区切る

単一フィールド内の

208 "Person" "Anne Myers" "unsigned long" "hello" -1 false false false

、いくつかの単語はスペースで区切られています。すなわち、「Anne Myers」。これは解析に問題です。

提案がありますか?出力はさらに処理するために9つのフィールドにする必要があります。 私の場合、フィールド内のスペースをある文字で置き換えることは実現できません。

編集:すべての行が同じフィールド順序に従います。

class field { 
    std::string content; 
public: 
    friend std::istream &operator>>(std::istream &is, field &f) { 
     char ch; 

     // skip whitespace, then read one character 
     is >> ch; 

     // If it's a quote, read to the next quote 
     if (ch == '"') 
      std::getline(is, f.content, '"'); 
     else { 
      // otherwise put it back, and read until white-space: 
      is.unget(); 
      std::getline(is, f.content); 
     } 
     return is; 
    } 

    // While we're at it, I'm going to define output so we can see what was 
    // read in a single field easily: 
    friend std::ostream &operator<<(std::ostream &os, field const &f) { 
     return os << "[" << f.content << "]"; 
    } 
}; 

はその後、我々は、単一の行のレコードタイプを定義することができ、適切なフィールドに、このタイプを使用しています。

+0

すべての行が同じフィールド順序とタイプに従っていますか?その場合は、正規表現を使用することができます。 – Sergey

+0

@Sergey go regex – mash

+0

この場合、何が出力されるべきですか。 – Shravan40

答えて

0

一つの可能​​な出発点は、正しくこの形式でデータを読み取るためにoperator>>をオーバーロードタイプになります:

struct foo { 
    int a; 
    field b; 
    field c; 
    field d; 
    field e; 
    int f; 
    bool g, h, i; 

    friend std::istream &operator>>(std::istream &is, foo &f) { 
     return is >> std::boolalpha 
        >> f.a 
        >> f.b 
        >> f.c 
        >> f.d 
        >> f.e 
        >> f.f 
        >> f.g 
        >> f.h 
        >> f.i; 
    } 

    friend std::ostream &operator<<(std::ostream &os, foo &f) { 
     return os << std::boolalpha 
        << f.a << " " 
        << f.b 
        << f.c 
        << f.d 
        << f.e << " " 
        << f.f << " " 
        << f.g << " " 
        << f.h << " " 
        << f.i; 
    } 
}; 

その後、我々は、レコードを読み書きテストすることができます。

int main() { 
    std::istringstream in 
     { R"(208 "Person" "Anne Myers" "unsigned long" "hello" -1 false false false)" }; 

    foo f; 

    in >> f; 
    std::cout << f; 
} 

結果:

208 [Person][Anne Myers][unsigned long][hello] -1 false false false 

これは、(現在は)また、引用符が含まれてフィールドに対処しようとしません。引用符をバックスラッシュでエスケープするCのような規則や、入力の行に2つの引用符を入れることで1つの引用符を含むCSVのような規則を使って可能です。例えば

"Bill said: ""Go away""!" 

...テキストを含む、一つのフィールドとして解析されます:

Bill said: "Go away"! 

のどちらかを追加することはかなり簡単ですが、あなたは(これは言っていませんもしあなたがサポートしたいと思っているなら、私は今のところそれを放棄しました。

関連する問題