20

我正在使用 boost::split 来解析数据文件。数据文件包含如下行。

数据.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

即使“相邻的分隔符合并在一起”,似乎尾随分隔符也会造成问题,因为即使将它们视为一个分隔符,它仍然一个分隔符。

所以你的问题不能单独解决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 来拆分(又名标记化)一行文本,但发现这个库更符合我的要求。

其中一件很棒的事情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 回答