20

boost::split を使用してデータ ファイルを解析しています。データ ファイルには、次のような行が含まれています。

data.txt

1:1~15  ASTKGPSVFPLAPSS SVFPLAPSS   -12.6   98.3    

項目間の空白はタブです。上記の行を分割する必要があるコードは次のとおりです。

std::string buf;
/*Assign the line from the file to buf*/
std::vector<std::string> dataLine;
boost::split( dataLine, buf , boost::is_any_of("\t "), boost::token_compress_on);       //Split data line
cout << dataLine.size() << endl;

上記のコード行では、5 の出力を取得する必要がありますが、6 を取得します。ドキュメントを読み込もうとしましたが、この解決策は、私が望むことを行う必要があるように見えます。明らかに何かが欠けています。ありがとう!

編集: dataLine で次のように forloop を実行すると、次の結果が得られます。

cout << "****" << endl;
for(int i = 0 ; i < dataLine.size() ; i ++) cout << dataLine[i] << endl;
cout << "****" << endl;


****
1:1~15
ASTKGPSVFPLAPSS
SVFPLAPSS
-12.6
98.3

****
4

3 に答える 3

19

「隣接するセパレーターは一緒にマージされます」とはいえ、1つとして扱われても1つのデリメーターであるため、末尾のデリメーターが問題を引き起こしているようです

したがって、あなたの問題は一人では解決できませんsplit()。しかし幸いなことに、Boost String Algo にはtrim()andtrim_if()があり、文字列の先頭と末尾から空白または区切りを取り除きます。したがってtrim()、次のように buf を呼び出すだけです。

std::string buf = "1:1~15  ASTKGPSVFPLAPSS SVFPLAPSS   -12.6   98.3    ";
std::vector<std::string> dataLine;
boost::trim_if(buf, boost::is_any_of("\t ")); // could also use plain boost::trim
boost::split(dataLine, buf, boost::is_any_of("\t "), boost::token_compress_on);
std::cout << out.size() << std::endl;

この質問はすでに尋ねられました: boost::split は文字列の最初と最後に空のトークンを残します - これは望ましい動作ですか?

于 2013-03-28T19:38:16.470 に答える
7

C++ String Toolkit Libraryの使用をお勧めします。私の意見では、このライブラリは Boost よりもはるかに高速です。以前は Boost を使用してテキスト行を分割 (別名トークン化) していましたが、このライブラリは私が求めているものとはるかに一致していることがわかりました。

素晴らしい点の 1 つは、strtk::parseトークンを最終的な値に変換し、要素の数をチェックすることです。

次のように使用できます。

std::vector<std::string> tokens;

// multiple delimiters should be treated as one
if( !strtk::parse( dataLine, "\t", tokens ) )
{
    std::cout << "failed" << std::endl;
}

--- 別バージョン

std::string token1;
std::string token2;
std::string token3:
float value1;
float value2;

if( !strtk::parse( dataLine, "\t", token1, token2, token3, value1, value2) )
{
     std::cout << "failed" << std::endl;
     // fails if the number of elements is not what you want
}

ライブラリのオンライン ドキュメント: String Tokenizer Documentation ソース コードへのリンク: C++ String Toolkit Library

于 2013-03-28T19:38:27.880 に答える
1

boost::split先頭と末尾の空白は、意味があるかどうかわからないため、意図的にそのままにしてあります。boost::trim解決策は、 を呼び出す前に使用することboost::splitです。

#include <boost/algorithm/string/trim.hpp>

....

boost::trim(buf);
于 2013-03-28T19:40:38.003 に答える