1

データ形式が「int、int、...、int、string、int」の場合、stringstream (のみ) を使用してフィールドを適切にデコードできますか?

[コード]

int main(int c, char** v)
{
    std::string line = "0,1,2,3,4,5,CT_O,6";
    char delimiter[7];
    int id, ag, lid, cid, fid, did, j = -12345;
    char dcontact[4]; // <- The size of <string-field> is known and fixed
    std::stringstream ssline(line);
    ssline >> id >> delimiter[0]
    >> ag >> delimiter[1]
    >> lid >> delimiter[2]
    >> cid >> delimiter[3]
    >> fid >> delimiter[4]
    >> did >> delimiter[5]  // <- should I do something here?
    >> dcontact >> delimiter[6]
    >> j;
    std::cout << id << ":" << ag << ":" << lid << ":" << cid << ":" << fid << ":" << did << ":";
    std::cout << dcontact << "\n";
}

[出力] 、太字の部分は、stringstream が dcontact に対してのみ 4 文字の読み取りに失敗したことを示しています。実際には 4 文字以上を保持し、ガベージ データを残します。0:1:2:3:4:5:CT_6,0:-45689dcontactj

4

5 に答える 5

1

もう少し堅牢です(','区切り文字を正しく処理します):

template <char D>
std::istream& delim(std::istream& in)
{
  char c;
  if (in >> c && c != D) in.setstate(std::ios_base::failbit);
  return in;
}

int main()
{
  std::string line = "0,1,2,3,4,5,CT_O,6";
  int id, ag, lid, cid, fid, did, j = -12345;
  char dcontact[5]; // <- The size of <string-field> is known and fixed
  std::stringstream ssline(line);
  (ssline >> id >> delim<','>
          >> ag >> delim<','>
          >> lid >> delim<','>
          >> cid >> delim<','>
          >> fid >> delim<','>
          >> did >> delim<','> >> std::ws
          ).get(dcontact, 5, ',') >> delim<','>
          >> j;
  std::cout << id << ":" << ag << ":" << lid << ":"
            << cid << ":" << fid << ":" << did << ":";
            << dcontact << "\n";
}
于 2013-01-03T13:35:25.927 に答える
1

はい、operator >> (istream&, char[N])for N の特定のオーバーロードはなく、 for があるためchar*、それが最適と見なされます。char* のオーバーロードは次の空白文字まで読み取るため、コンマで停止しません。

dcontact を構造体でラップし、特定のオーバーロードを構造体に読み込むことができます。それ以外の場合は、read を使用できますが、素敵な>>演算子のチェーンが壊れます。

ssline.read( dcontact, 4 );

その時点で動作します。

ちなみに、区切り文字まで読み取るには、 を使用できますgetline。(getも機能しますgetlineが、 a への自由関数書き込みはstd::string、長さを推測する必要がないことを意味します)。

(他の人がgetではなくを使用するように指定していることに注意してください。ただし、null ターミネータ用に配列readの最後に余分なバイトがないため、これは失敗します。null で終了する場合は、5 にします。文字と 'get` を使用すると、null が追加されます)。dcontactdcontact

于 2013-01-03T13:27:29.687 に答える
0

これを試して

  int main(int c, char** v) {
    string line = "0,1,2,3,4,5,CT_O,6";
    char delimiter[7];
    int id, ag, lid, cid, fid, did, j = -12345;
    char dcontact[5]; // <- The size of <string-field> is known and fixed

    stringstream ssline(line);

    ssline >> id >> delimiter[0]
            >> ag >> delimiter[1]
            >> lid >> delimiter[2]
            >> cid >> delimiter[3]
            >> fid >> delimiter[4]
            >> did >> delimiter[5];

    ssline.get(dcontact, 5);

    ssline >> delimiter[6]
            >> j;
    std::cout << id << ":" << ag << ":" << lid << ":" << cid << ":" << fid << ":" << did << ":";
    std::cout << dcontact << "\n" << j;
    }
于 2013-01-03T13:31:20.320 に答える
0

文字列の長さはわかっているので、次のようstd::setw(4)に を使用できます。

ssline >> std::setw(4) >> dcontact >> delimiter[6];
于 2013-01-05T00:10:42.607 に答える