将长字符串分成多个c ++

break long string into multiple c++

我有一个从第三方收到的字符串。这个字符串实际上是来自文本文件的文本,它可能包含用于行终止的unix-lf或windows-crlf。如何将其拆分为多个字符串而忽略空白行?我本来打算做以下工作,但不确定是否有更好的方法。我只需要一行一行地读。这里的向量只是一个方便,我可以避免它。*很遗憾,我没有访问实际文件的权限。我只接收字符串对象*

1
2
3
4
5
6
7
8
9
10
11
12
13
string textLine;
vector<string> tokens;

size_t pos = 0;
while( true ) {
    size_t nextPos = textLine.find( pos, '

'
);
    if( nextPos == textLine.npos )
        break;
    tokens.push_back( string( textLine.substr( pos, nextPos - pos ) ) );
    pos = nextPos + 1;
}


您可以使用std::getline,因为您是在从文件中读取数据,而不是将整个数据读取到一个字符串中。默认情况下,这会一行一行地将事情分解。你不能简单地把空字符串向后推。

1
2
3
4
5
6
7
string line;
vector<string> tokens;

while (getline(file, line))
{
    if (!line.empty()) tokens.push_back(line);
}

更新:

如果您没有访问该文件的权限,则可以通过用整个文本初始化stringstream来使用相同的代码。std::getline适用于所有流类型,而不仅仅是文件。


我将使用getline创建基于的新字符串,然后操作行尾。

1
2
3
4
5
6
7
8
9
10
11
12
string textLine;
vector<string> tokens;

istringstream sTextLine;
string line;
while(getline(sTextLine, line)) {
  if(line.empty()) continue;
  if(line[line.size()-1] == '
'
) line.resize(line.size()-1);
  if(line.empty()) continue;
  tokens.push_back(line);
}

编辑:用istringstream代替stringstream


在STD::STD::STEDIGHT:…

使用令牌分裂C++ STD::字符串,例如";";

…除了将";"参数忽略为STD::GETLIN。


很大程度上取决于工具箱中已经存在的内容。我工作很多使用来自Windows并在Unix下读取的文件,以及反之亦然,所以我有很多将CRLF转换为LF的工具。如果您没有,那么您可能需要一个沿着以下行的函数:

1
2
3
4
5
6
7
8
9
10
void addLine( std::vector<std::string>& dest, std::string line )
{
    if ( !line.empty() && *(line.end() - 1) == '
'
) {
        line.erase( line.end() - 1 );
    }
    if ( !line.empty() ) {
        dest.push_back( line );
    }
}

做你的插入。把原文分成几行,你可以像其他人一样使用std::istringstreamstd::getline。建议;这是简单和直接的,即使它是多余的。(std::istringstream是一个相当重的机构,因为它支持您不需要的各种输入转换。)或者,您可能会考虑沿着以下线条的循环:

1
2
3
4
5
6
7
8
9
10
11
std::string::const_iterator start = textLine.begin();
std::string::const_iterator end   = textLine.end();
std::string::const_iterator next  = std::find( start, end, '
'
);
while ( next != end ) {
    addLine( tokens, std::string( start, next ) );
    start = next + 1;
    next = std::find( start, end, '
'
);
}
addLine( tokens, std::string( start, end ) );

或者你可以把事情分解成不同的操作:

1
2
3
4
textLine.erase(
    std::remove( textLine.begin(), textLine.end(), '
'
),
    textLine.end() );

为了摆脱所有的CR,

1
2
std::vector<std:;string> tokens( split( textLine, '
'
) );

,将其分解为若干行,其中split是一个广义函数。沿着上面的循环线(一个有用的工具来添加到工具箱),最后:

1
2
3
4
tokens.erase(
    std::remove_if( tokens.begin(), tokens.end(),
                    boost::bind( &std::string::empty, _1 ) ),
    tokens.end() );

. (一般来说,如果这是一种情况,使用基于std::istringstream的解决方案。如果你认为你必须这么做在以后的一些时候,加上split。功能到您的随身携带的工具包,并使用它。)


我将把字符串放入StringStream,然后使用前面提到的getline方法。然后,您可以表现得像是从一个文件中读取文本,而实际上它来自另一个字符串。


你可以用Strtok。

Split string into tokens

A sequence of calls to this function
split str into tokens, which are
sequences of contiguous characters
separated by any of the characters
that are part of delimiters.